commit fe97754c45294ddf5927a86b6bfcc2c257cbadfe
parent 77b642144cfff5008542dd9b7f61ce7d5ed80b95
Author: Kyle Milz <kyle@green.krwm.net>
Date: Sat, 20 Feb 2016 15:23:23 -0700
ios: misc cleanups
- fix ~20 warnings
- remove duplicated code in Network.m
- assign notification requests with functions better
- {input,output}ShlistStream -> {input,output}_stream
- add a read_all function in Network.m
Diffstat:
8 files changed, 112 insertions(+), 150 deletions(-)
diff --git a/ios/ContactsTableViewController.m b/ios/ContactsTableViewController.m
@@ -76,8 +76,8 @@
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
- int section = [indexPath section];
- int row = [indexPath row];
+ NSInteger section = [indexPath section];
+ NSInteger row = [indexPath row];
Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row];
UITableViewCell *cell;
@@ -117,8 +117,8 @@
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
- int section = [indexPath section];
- int row = [indexPath row];
+ NSInteger section = [indexPath section];
+ NSInteger row = [indexPath row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
@@ -142,8 +142,8 @@
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
- NSLog(@"info: selected %@ %@ who has %i phone numbers",
- contact.first_name, contact.last_name, [contact.phone_numbers count]);
+ NSLog(@"info: selected %@ %@ who has %lu phone numbers",
+ contact.first_name, contact.last_name, (unsigned long)[contact.phone_numbers count]);
}
// programatically assign section headers, in this case they're letters
diff --git a/ios/EditItemTableViewController.m b/ios/EditItemTableViewController.m
@@ -123,7 +123,7 @@
[buffer appendData:[[string_array componentsJoinedByString:@":"] dataUsingEncoding:NSUTF8StringEncoding]];
// the list item that was just edited will be updated when a response comes
- [network_connection send_message:7 contents:buffer];
+ //[network_connection send_message:7 contents:buffer];
NSLog(@"debug: %@: %@: saving", _list.name, _item.name);
}
diff --git a/ios/shlist.xcodeproj/project.pbxproj b/ios/shlist.xcodeproj/project.pbxproj
@@ -22,8 +22,6 @@
27C70F301B33F4FA00DADEB3 /* MainTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C70F2F1B33F4FA00DADEB3 /* MainTableViewController.m */; };
27D805731BA2649D00867494 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D805721BA2649D00867494 /* ContactsTableViewController.m */; };
27D83D2A1BAFC99D0029F54B /* EditTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D83D291BAFC99D0029F54B /* EditTableViewController.m */; };
- 27DCC9DE1B8A98D400207340 /* dollar103-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9DD1B8A98D400207340 /* dollar103-2.png */; };
- 27DCC9E81B9EB4E800207340 /* information15-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9E71B9EB4E800207340 /* information15-3.png */; };
27DCC9EB1B9FF89E00207340 /* AddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 27DCC9EA1B9FF89E00207340 /* AddressBook.m */; };
BF7776B91B38928D00526CB0 /* ListTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF7776B81B38928D00526CB0 /* ListTableViewController.m */; };
/* End PBXBuildFile section */
@@ -68,8 +66,6 @@
27D805721BA2649D00867494 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTableViewController.m; sourceTree = SOURCE_ROOT; };
27D83D281BAFC99D0029F54B /* EditTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditTableViewController.h; sourceTree = "<group>"; };
27D83D291BAFC99D0029F54B /* EditTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditTableViewController.m; sourceTree = "<group>"; };
- 27DCC9DD1B8A98D400207340 /* dollar103-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dollar103-2.png"; path = "../../../Downloads/dollar103-2.png"; sourceTree = "<group>"; };
- 27DCC9E71B9EB4E800207340 /* information15-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "information15-3.png"; path = "../../../Downloads/information15-3.png"; sourceTree = "<group>"; };
27DCC9E91B9FF89E00207340 /* AddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddressBook.h; sourceTree = "<group>"; };
27DCC9EA1B9FF89E00207340 /* AddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddressBook.m; sourceTree = "<group>"; };
BF7776B71B38928D00526CB0 /* ListTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListTableViewController.h; sourceTree = "<group>"; };
@@ -126,13 +122,11 @@
27D805721BA2649D00867494 /* ContactsTableViewController.m */,
27C70F281B33CE2500DADEB3 /* DataStructures.h */,
27C70F291B33D1C900DADEB3 /* DataStructures.m */,
- 27DCC9DD1B8A98D400207340 /* dollar103-2.png */,
27AAC22A1B50ABAF00D99171 /* EditItemTableViewController.h */,
27AAC22B1B50ABAF00D99171 /* EditItemTableViewController.m */,
27D83D281BAFC99D0029F54B /* EditTableViewController.h */,
27D83D291BAFC99D0029F54B /* EditTableViewController.m */,
27C70F0F1B32AF8000DADEB3 /* Images.xcassets */,
- 27DCC9E71B9EB4E800207340 /* information15-3.png */,
27C70F111B32AF8000DADEB3 /* LaunchScreen.xib */,
BF7776B71B38928D00526CB0 /* ListTableViewController.h */,
BF7776B81B38928D00526CB0 /* ListTableViewController.m */,
@@ -259,9 +253,7 @@
files = (
27C70F0E1B32AF8000DADEB3 /* Main.storyboard in Resources */,
27C70F131B32AF8000DADEB3 /* LaunchScreen.xib in Resources */,
- 27DCC9E81B9EB4E800207340 /* information15-3.png in Resources */,
27C70F101B32AF8000DADEB3 /* Images.xcassets in Resources */,
- 27DCC9DE1B8A98D400207340 /* dollar103-2.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/ios/shlist/AppDelegate.m b/ios/shlist/AppDelegate.m
@@ -38,7 +38,9 @@
NSMutableDictionary *request = [[NSMutableDictionary alloc] init];
[request setObject:hex_token forKey:@"pushtoken_hex"];
- [network_connection send_message:device_update contents:request];
+ if ([network_connection get_device_id] != nil) {
+ [network_connection send_message:device_update contents:request];
+ }
}
// Called when push notification received
@@ -96,7 +98,9 @@
// background.
NSLog(@"info: app: entering foreground, reconnecting...");
- [network_connection send_message:lists_get contents:[[NSMutableDictionary alloc] init]];
+ [network_connection connect];
+ //[network_connection send_message:lists_get contents:[[NSMutableDictionary alloc] init]];
+ //[network_connection send_message:lists_get_other contents:[[NSMutableDictionary alloc] init]];
}
- (void) applicationDidBecomeActive:(UIApplication *)application
diff --git a/ios/shlist/ListTableViewController.m b/ios/shlist/ListTableViewController.m
@@ -170,9 +170,9 @@
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0)
- return [NSString stringWithFormat:@"Shared Items (%i)", [_list_items count]];
+ return [NSString stringWithFormat:@"Shared Items (%lu)", (unsigned long)[_list_items count]];
else if (section == 1)
- return [NSString stringWithFormat:@"Private Items (%i)", [_private_items count]];
+ return [NSString stringWithFormat:@"Private Items (%lu)", (unsigned long)[_private_items count]];
return @"";
}
diff --git a/ios/shlist/MainTableViewController.m b/ios/shlist/MainTableViewController.m
@@ -43,32 +43,25 @@
[default_center addObserver:self selector:@selector(push_updated_list:)
name:@"PushNotification_updated_list" object:nil];
- // Hook up generic message handlers
- notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", lists_get];
- [default_center addObserver:self selector:@selector(lists_get_finished:)
- name:notification_name object:nil];
-
- notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", lists_get_other];
- [default_center addObserver:self selector:@selector(lists_get_other_finished:)
- name:notification_name object:nil];
-
- notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", list_add];
- [default_center addObserver:self selector:@selector(finished_new_list_request:)
- name:notification_name object:nil];
-
- notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", list_join];
- [default_center addObserver:self selector:@selector(finished_join_list_request:)
- name:notification_name object:nil];
-
- notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", list_leave];
- [default_center addObserver:self selector:@selector(finished_leave_list_request:)
- name:notification_name object:nil];
-
+ const SEL selectors[] = {
+ @selector(lists_get_finished:),
+ @selector(lists_get_other_finished:),
+ @selector(finished_new_list_request:),
+ @selector(finished_join_list_request:),
+ @selector(finished_leave_list_request:)
+ };
+ NSUInteger count = 0;
+
+ // This object handles responses for these types of messages
+ for (id str in @[@"lists_get", @"lists_get_other", @"list_add", @"list_join", @"list_leave"]) {
+ notification_name = [NSString stringWithFormat:@"NetworkResponseFor_%@", str];
+ [default_center addObserver:self selector:selectors[count] name:notification_name object:nil];
+ count++;
+ }
// display an Edit button in the navigation bar for this view controller
self.navigationItem.leftBarButtonItem = self.editButtonItem;
- // there's a race here when assigning self
network_connection = [Network shared_network_connection];
_lists = [[NSMutableArray alloc] init];
@@ -227,7 +220,7 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
{
}
-- (void) lists_get_finished:(NSNotification *)notification;
+- (void) lists_get_finished:(NSNotification *)notification
{
NSDictionary *response = notification.userInfo;
@@ -252,7 +245,7 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSDictionary *response = notification.userInfo;
NSArray *other_json_lists = [response objectForKey:@"other_lists"];
- NSLog(@"lists_get_other: got %i other lists from server", [other_json_lists count]);
+ NSLog(@"lists_get_other: got %lu other lists from server", (unsigned long)[other_json_lists count]);
NSMutableArray *other_lists = [_lists objectAtIndex:1];
[other_lists removeAllObjects];
@@ -510,14 +503,14 @@ titleForHeaderInSection:(NSInteger)section
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:@"SharedListPrototypeCell" forIndexPath:indexPath];
- int section = [indexPath section];
- int row = [indexPath row];
+ NSInteger section = [indexPath section];
+ NSInteger row = [indexPath row];
SharedList *shared_list = [[_lists objectAtIndex:section] objectAtIndex:row];
UILabel *deadline_label = (UILabel *)[cell viewWithTag:3];
UILabel *fraction_label = (UILabel *)[cell viewWithTag:4];
- if ([indexPath section] == 0) {
+ if (section == 0) {
// your lists section
if (shared_list.date == nil) {
@@ -539,7 +532,7 @@ titleForHeaderInSection:(NSInteger)section
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
- else if ([indexPath section] == 1) {
+ else if (section == 1) {
// "other lists" section
// no deadline
diff --git a/ios/shlist/Network.h b/ios/shlist/Network.h
@@ -3,8 +3,8 @@
#import "MsgTypes.h"
@interface Network : NSObject <NSStreamDelegate> {
- NSInputStream *inputShlistStream;
- NSOutputStream *outputShlistStream;
+ NSInputStream *input_stream;
+ NSOutputStream *output_stream;
}
- (void) connect;
@@ -19,4 +19,4 @@
// returns singleton instance
+ (id) shared_network_connection;
-@end
-\ No newline at end of file
+@end
diff --git a/ios/shlist/Network.m b/ios/shlist/Network.m
@@ -55,27 +55,23 @@
CFWriteStreamRef writeStream;
CFStringRef host_name = CFSTR("absentmindedproductions.ca");
-
CFStreamCreatePairWithSocketToHost(NULL, host_name, 9999, &readStream, &writeStream);
- inputShlistStream = (__bridge NSInputStream *)readStream;
- outputShlistStream = (__bridge NSOutputStream *)writeStream;
- [inputShlistStream setDelegate:self];
- [outputShlistStream setDelegate:self];
+ input_stream = (__bridge NSInputStream *)readStream;
+ output_stream = (__bridge NSOutputStream *)writeStream;
- [inputShlistStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- [outputShlistStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [input_stream setDelegate:self];
+ [output_stream setDelegate:self];
- // Enable SSL on both streams
- [inputShlistStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
- [outputShlistStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
+ [input_stream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [output_stream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- [inputShlistStream open];
- [outputShlistStream open];
+ // Enable SSL on both streams
+ [input_stream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
+ [output_stream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
- NSLog(@"network: connect()");
- connected = 1;
- [[NSNotificationCenter defaultCenter] postNotificationName:@"NetworkConnectedNotification" object:nil userInfo:nil];
+ [input_stream open];
+ [output_stream open];
}
- (void) disconnect
@@ -84,16 +80,16 @@
connected = 0;
[[NSNotificationCenter defaultCenter] postNotificationName:@"NetworkDisconnectedNotification" object:nil userInfo:nil];
- [inputShlistStream close];
- [outputShlistStream close];
+ [input_stream close];
+ [output_stream close];
- [inputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
+ [input_stream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
- [outputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
+ [output_stream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
- inputShlistStream = nil; // stream is ivar, so reinit it
- outputShlistStream = nil; // stream is ivar, so reinit it
+ input_stream = nil; // stream is ivar, so reinit it
+ output_stream = nil; // stream is ivar, so reinit it
}
- (bool) load_device_id:(NSString *)phone_number;
@@ -113,44 +109,21 @@
}
// no device id file found, send a registration message
- NSMutableData *msg = [NSMutableData data];
-
- NSDictionary *request = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *request = [NSMutableDictionary dictionaryWithObjectsAndKeys:
phone_number, @"phone_number",
@"ios", @"os",
nil];
+ [self send_message:device_add contents:request];
- NSError *error = nil;
- NSData *json = [NSJSONSerialization dataWithJSONObject:request options:0 error:&error];
- if (error != nil) {
- NSLog(@"%@", [error userInfo]);
- return false;
- }
-
- uint16_t version = htons(0);
- uint16_t msg_type = htons(device_add);
- uint16_t length = htons([json length]);
- [msg appendBytes:&version length:2];
- [msg appendBytes:&msg_type length:2];
- [msg appendBytes:&length length:2];
-
- // Append JSON payload
- [msg appendData:json];
-
- [outputShlistStream write:[msg bytes] maxLength:[msg length]];
- NSLog(@"register: sent request");
-
- // we don't have a device id so we can't do anything yet
return false;
}
- (bool) send_message:(uint16_t)send_msg_type contents:(NSMutableDictionary *)request
{
- if (!connected)
- [self connect];
-
- // Append 'device_id' to all message requests sent through this function
- [request setObject:device_id forKey:@"device_id"];
+ if (send_msg_type != device_add) {
+ // Append 'device_id' to all message types except device_add
+ [request setObject:device_id forKey:@"device_id"];
+ }
NSError *error = nil;
// Try to serialize request, bail if errors
@@ -172,20 +145,10 @@
[msg appendBytes:&length length:2];
[msg appendData:json];
- NSLog(@"network: send_message: type %i, %i bytes",
- send_msg_type, [msg length]);
-
- if ([outputShlistStream write:[msg bytes] maxLength:[msg length]] == -1) {
- NSLog(@"network: write error occurred, trying reconnect");
- if (connected)
- [self disconnect];
- [self connect];
+ NSLog(@"network: send_message: type %i, %lu bytes",
+ send_msg_type, (unsigned long)[msg length]);
- if ([outputShlistStream write:[msg bytes] maxLength:[msg length]] == -1) {
- NSLog(@"network: resend failed after reconnect, giving up");
- return false;
- }
- }
+ [output_stream write:[msg bytes] maxLength:[msg length]];
// sent successfully
return true;
@@ -194,10 +157,10 @@
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
NSString *stream_name;
- if (stream == inputShlistStream)
- stream_name = @"input";
- else if (stream == outputShlistStream)
- stream_name = @"output";
+ if (stream == input_stream)
+ stream_name = @"input stream";
+ else if (stream == output_stream)
+ stream_name = @"output stream";
switch (eventCode) {
case NSStreamEventNone: {
@@ -206,39 +169,41 @@
}
case NSStreamEventOpenCompleted: {
NSLog(@"network: %@ opened", stream_name);
+
+ connected = 1;
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NetworkConnectedNotification" object:nil userInfo:nil];
break;
}
case NSStreamEventHasBytesAvailable: {
- NSLog(@"network: %@ has bytes available", stream_name);
-
- if (stream == inputShlistStream) {
- if (![inputShlistStream hasBytesAvailable]) {
- NSLog(@"read: input stream had no bytes available");
- break;
- }
+ // NSLog(@"network: %@ has bytes available", stream_name);
- [self read_ready];
+ if (stream != input_stream) {
+ break;
}
+
+ // Read an entire message, header + payload
+ [self read_ready];
+
break;
}
case NSStreamEventHasSpaceAvailable: {
- NSLog(@"network: %@ has space available", stream_name);
+ // NSLog(@"network: %@ has space available", stream_name);
break;
}
case NSStreamEventErrorOccurred: {
// happens when trying to connect to a down server
NSStream *error_stream;
- if (stream == inputShlistStream)
- error_stream = inputShlistStream;
- else if (stream == outputShlistStream)
- error_stream = outputShlistStream;
+ if (stream == input_stream)
+ error_stream = input_stream;
+ else if (stream == output_stream)
+ error_stream = output_stream;
else
// don't try to do operations on null stream
break;
NSError *theError = [error_stream streamError];
- NSLog(@"network: %@", [NSString stringWithFormat:@"%@ error %i: %@",
- stream_name, [theError code], [theError localizedDescription]]);
+ NSLog(@"network: %@", [NSString stringWithFormat:@"%@ error %li: %@",
+ stream_name, (long)[theError code], [theError localizedDescription]]);
[self disconnect];
@@ -255,20 +220,20 @@
}
}
+// Try to read and parse an entire message. If the messsage type isn't device_add,
+// then send a notification to the classes responsible
- (void) read_ready
{
- NSInteger buffer_len;
+ // Read header
uint16_t header[3];
+ [self read_all:(uint8_t *)header size:6];
- buffer_len = [inputShlistStream read:(uint8_t *)header maxLength:6];
- if (buffer_len != 6) {
- NSLog(@"read: didn't return 6 bytes");
- }
-
+ // Unpack header
uint16_t version = ntohs(header[0]);
uint16_t msg_type = ntohs(header[1]);
uint16_t payload_size = ntohs(header[2]);
+ // Verify header
if (version != 0) {
NSLog(@"read: invalid version %i", version);
return;
@@ -278,20 +243,16 @@
return;
}
+ // Read payload, accept up to 64KB of data
uint8_t *payload = malloc(payload_size);
+ [self read_all:payload size:payload_size];
+ NSLog(@"read: payload is %i bytes", payload_size);
- // Accept up to 64KB of data, the maximum size of payload_size
- buffer_len = [inputShlistStream read:payload maxLength:payload_size];
- if (buffer_len != payload_size) {
- NSLog(@"read: expected %i byte payload but got %i", payload_size, buffer_len);
- return;
- }
- NSLog(@"read: payload is %i bytes", buffer_len);
-
+ // Create new NSData wrapper around the payload bytes
NSData *data = [NSData dataWithBytesNoCopy:payload length:payload_size];
NSError *error = nil;
- // Try to parse payload and check for errors
+ // Try to parse the payload as JSON, check for errors
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data
options:0 error:&error];
if (error) {
@@ -324,11 +285,24 @@
return;
}
- // Send a generic notification, these have to be hooked up to work
- NSString *notification_name = [NSString stringWithFormat:@"NetworkResponseForMsgType%i", msg_type];
+ // Send out a notification that a response was received. The responsible
+ // parties should already be listening for these by the time they come in.
+ NSString *notification_name = [NSString stringWithFormat:@"NetworkResponseFor_%s", msg_strings[msg_type]];
[[NSNotificationCenter defaultCenter] postNotificationName:notification_name object:nil userInfo:response];
}
+// Read a fixed amount of bytes
+- (NSInteger) read_all:(uint8_t *)data size:(unsigned int)size
+{
+ NSInteger buffer_len = [input_stream read:data maxLength:size];
+ if (buffer_len != size) {
+ NSLog(@"read_all: read %ld instead of %d bytes", (long)buffer_len, size);
+ return buffer_len;
+ }
+
+ return buffer_len;
+}
+
- (void) dealloc
{
[self disconnect];