shlist

share and manage lists between multiple people
Log | Files | Refs

commit 932e525815e5c8d9b527c549986cb1db5399b912
parent 1758545453a9db72ad72c6def48053bcdacdfd0f
Author: Kyle Milz <kyle@green.krwm.net>
Date:   Wed, 27 Jan 2016 20:24:25 -0700

ios: implement beginnings of push notifications

- right now we can receive push notifications and can update the server with our
  token
- send the token as hex for now as that's the format it needs to be in
  eventually anyways
- there's some lists_get_other changes rolled in here too

Diffstat:
Mios/shlist.xcodeproj/project.pbxproj | 10++++++----
Mios/shlist/AppDelegate.m | 40+++++++++++++++++++++++++++++++++++++++-
Mios/shlist/DataStructures.h | 3++-
Mios/shlist/Info.plist | 2+-
Mios/shlist/MainTableViewController.h | 1+
Mios/shlist/MainTableViewController.m | 63+++++++++++++++++++++++++++++++++++++++++++++------------------
Mios/shlist/Network.m | 26+++++++++++++++++++++-----
7 files changed, 115 insertions(+), 30 deletions(-)

diff --git a/ios/shlist.xcodeproj/project.pbxproj b/ios/shlist.xcodeproj/project.pbxproj @@ -419,12 +419,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; INFOPLIST_FILE = shlist/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE = "f4fadd8d-5f11-416b-9be6-e8f86ac522d7"; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -433,12 +434,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; INFOPLIST_FILE = shlist/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE = "f4fadd8d-5f11-416b-9be6-e8f86ac522d7"; + TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; diff --git a/ios/shlist/AppDelegate.m b/ios/shlist/AppDelegate.m @@ -15,10 +15,42 @@ // we need to issue connect/reconnects from here network_connection = [Network shared_network_connection]; + // Register the supported interaction types. + [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge]; + // customization after application launch return YES; } +// Handle remote notification registration. +- (void)application:(UIApplication *)app + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken +{ + const unsigned char *token_data = [devToken bytes]; + NSUInteger token_length = [devToken length]; + + NSMutableString *hex_token = [NSMutableString stringWithCapacity:(token_length * 2)]; + for (int i = 0; i < token_length; i++) { + [hex_token appendFormat:@"%02X", (NSUInteger)token_data[i]]; + } + + NSLog(@"apn: device token is 0x%@", hex_token); + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + [request setObject:hex_token forKey:@"pushtoken_hex"]; + [network_connection send_message:device_update contents:request]; +} + +// Called when push notification received +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +{ + NSLog(@"notify: got remote notification"); + for (id key in userInfo) { + NSLog(@"notify: '%@' => '%@'", key, userInfo[key]); + } + [[NSNotificationCenter defaultCenter] postNotificationName:@"PushNotificationMessageReceivedNotification" object:nil userInfo:userInfo]; +} + - (void) applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive @@ -52,7 +84,7 @@ // background. NSLog(@"info: app: entering foreground, reconnecting..."); - [network_connection send_message:3 contents:nil]; + [network_connection send_message:lists_get contents:[[NSMutableDictionary alloc] init]]; } - (void) applicationDidBecomeActive:(UIApplication *)application @@ -71,4 +103,10 @@ [network_connection disconnect]; } +- (void)application:(UIApplication *)app + didFailToRegisterForRemoteNotificationsWithError:(NSError *)err +{ + NSLog(@"Error in registration. Error: %@", err); +} + @end \ No newline at end of file diff --git a/ios/shlist/DataStructures.h b/ios/shlist/DataStructures.h @@ -9,11 +9,12 @@ @property NSString *name; @property NSNumber *num; +@property NSNumber *items_total; @property NSArray *members_phone_nums; @property bool deadline; @property NSDate *date; @property NSNumber *items_ready; -@property NSNumber *items_total; + @property UITableViewCell *cell; @end diff --git a/ios/shlist/Info.plist b/ios/shlist/Info.plist @@ -7,7 +7,7 @@ <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> - <string>octopus.$(PRODUCT_NAME:rfc1034identifier)</string> + <string>com.octopus.$(PRODUCT_NAME:rfc1034identifier)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> diff --git a/ios/shlist/MainTableViewController.h b/ios/shlist/MainTableViewController.h @@ -7,6 +7,7 @@ - (void) update_address_book; - (void) lists_get_finished:(NSArray *)lists; +- (void) lists_get_other_finished:(NSArray *)other_lists; - (void) finished_new_list_request:(SharedList *) shlist; - (void) finished_join_list_request:(SharedList *) shlist; - (void) finished_leave_list_request:(SharedList *) shlist; diff --git a/ios/shlist/MainTableViewController.m b/ios/shlist/MainTableViewController.m @@ -48,9 +48,14 @@ if ([self load_phone_number]) { // phone number loaded, try loading device id if ([network_connection load_device_id:phone_number]) { - // bulk update, doesn't take a payload + + // Send lists_get request, no arguments required here NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; [network_connection send_message:lists_get contents:dict]; + + // Send lists_get_other request, no arguments here either + [dict removeAllObjects]; + [network_connection send_message:lists_get_other contents:dict]; } // else, device id request sent } @@ -73,7 +78,7 @@ } UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Important" - message:@"Your phone number is needed for us to calculate your mutual contacts. Severe amounts of functionality disabled." + message:@"Your phone number is needed for us to calculate your mutual contacts. Expect severe functionality loss." delegate:self cancelButtonTitle:@"Nope" otherButtonTitles:@"Ok", nil]; alert.alertViewStyle = UIAlertViewStylePlainTextInput; @@ -171,18 +176,41 @@ clickedButtonAtIndex:(NSInteger)buttonIndex [lists removeAllObjects]; for (NSDictionary *list in json_lists) { - SharedList *tmp = [[SharedList alloc] init]; - tmp.num = [list objectForKey:@"num"]; - tmp.name = [list objectForKey:@"name"]; - // tmp.date = [list objectForKey:@"date"]; - tmp.items_ready = [list objectForKey:@"items_complete"]; - tmp.items_total = [list objectForKey:@"items_total"]; - NSArray *members = [list objectForKey:@"members"]; - tmp.members_phone_nums = members; + tmp.num = list[@"num"]; + + NSData *name_data = [list[@"name"] dataUsingEncoding:NSISOLatin1StringEncoding]; + tmp.name = [[NSString alloc] initWithData:name_data encoding:NSUTF8StringEncoding]; + + NSNumber *date = list[@"date"]; + tmp.date = [NSDate dateWithTimeIntervalSince1970:[date floatValue]]; + tmp.members_phone_nums = list[@"members"]; + tmp.items_ready = list[@"items_complete"]; + tmp.items_total = list[@"items_total"]; [lists addObject:tmp]; - NSLog(@"adding list '%@'", [list objectForKey:@"name"]); + NSLog(@"adding list '%@', num '%@'", tmp.name, tmp.num); + } + + [self.tableView reloadData]; +} + +- (void) lists_get_other_finished:(NSArray *)other_json_lists; +{ + NSMutableArray *other_lists = [_lists objectAtIndex:1]; + [other_lists removeAllObjects]; + + for (NSDictionary *list in other_json_lists) { + SharedList *tmp = [[SharedList alloc] init]; + tmp.num = list[@"num"]; + + NSData *name_data = [list[@"name"] dataUsingEncoding:NSISOLatin1StringEncoding]; + tmp.name = [[NSString alloc] initWithData:name_data encoding:NSUTF8StringEncoding]; + + tmp.members_phone_nums = list[@"members"]; + [other_lists addObject:tmp]; + + NSLog(@"adding other list '%@', num '%@'", tmp.name, tmp.num); } [self.tableView reloadData]; @@ -214,8 +242,9 @@ clickedButtonAtIndex:(NSInteger)buttonIndex NSLog(@"info: joining list '%@'", list.name); // the response for this does all of the heavy row moving work - int num = list.num; - [network_connection send_message:list_join contents:[NSData dataWithBytes:&num length:sizeof(num)]]; + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + [request setObject:list.num forKey:@"num"]; + [network_connection send_message:list_join contents:request]; } - (void) finished_join_list_request:(SharedList *) shlist @@ -402,11 +431,11 @@ clickedButtonAtIndex:(NSInteger)buttonIndex // should not happen return @""; - int total = [[_lists objectAtIndex:section] count]; + NSUInteger total = [[_lists objectAtIndex:section] count]; if (section == 0) - return [NSString stringWithFormat:@"Lists you're in (%i)", total]; + return [NSString stringWithFormat:@"Lists you're in (%lu)", (unsigned long)total]; else if (section == 1) - return [NSString stringWithFormat:@"Other lists (%i)", total]; + return [NSString stringWithFormat:@"Other lists (%lu)", (unsigned long)total]; return @""; } @@ -493,10 +522,8 @@ clickedButtonAtIndex:(NSInteger)buttonIndex } [result appendString:@"/"]; - return result; NSString *two = [denominator stringValue]; - for (int i = 0; i < two.length; i++) { [result appendString:[self subscript:[[two substringWithRange:NSMakeRange(i, 1)] intValue]]]; } diff --git a/ios/shlist/Network.m b/ios/shlist/Network.m @@ -272,8 +272,8 @@ return; } - const char *payload = malloc(payload_size); - buffer_len = [inputShlistStream read:(uint8_t *)payload maxLength:payload_size]; + uint8_t *payload = malloc(payload_size); + buffer_len = [inputShlistStream read:payload maxLength:payload_size]; if (buffer_len != payload_size) { [self error:@"read: expected %i byte payload but got %i", payload_size, buffer_len]; return; @@ -284,10 +284,11 @@ NSError *error = nil; NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data - options:NSJSONReadingAllowFragments error:&error]; + options:0 error:&error]; if (error) { NSLog(@"%@", [error userInfo]); - }; + return; + } NSString *status = [response objectForKey:@"status"]; if (status == nil) { @@ -295,7 +296,7 @@ return; } if ([status compare:@"err"] == 0) { - NSLog(@"read: response error, reason = '%@'", [response objectForKey:@"reason"]); + NSLog(@"read: response error, reason = '%@'", [response valueForKey:@"reason"]); return; } @@ -307,6 +308,8 @@ [self lists_get:response]; } else if (msg_type == list_join) { [self list_join:response]; + } else if (msg_type == lists_get_other) { + [self lists_get_other:response]; } // free((void *)payload); @@ -356,6 +359,19 @@ [shlist_tvc lists_get_finished:lists]; } +- (void) lists_get_other:(NSDictionary *)response +{ + NSArray *other_lists = [response objectForKey:@"other_lists"]; + NSLog(@"lists_get_other: got %i other lists from server", [other_lists count]); + + // Don't attempt to update a view controller that isn't there yet + if (![self check_tvc:shlist_tvc]) + return; + + if (shlist_tvc) + [shlist_tvc lists_get_other_finished:other_lists]; +} + - (void) list_join:(NSDictionary *)response { SharedList *shlist = [[SharedList alloc] init];