From 06ab218ac9e66c5a3734b4090f7fded4b36f3164 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Thu, 17 Nov 2016 19:53:46 -0800 Subject: [PATCH] Stubbing in APNS push notifications in iOS. Looks for feed notifications for iOS, then requests push notifications. Sends token back to server. Still needs to handle notification and eventually edit notifications. --- clients/ios/Classes/NewsBlurAppDelegate.h | 1 + clients/ios/Classes/NewsBlurAppDelegate.m | 59 +++++++++++++++++- clients/ios/Classes/NewsBlurViewController.m | 62 +++++-------------- .../ios/NewsBlur.xcodeproj/project.pbxproj | 13 +++- 4 files changed, 85 insertions(+), 50 deletions(-) diff --git a/clients/ios/Classes/NewsBlurAppDelegate.h b/clients/ios/Classes/NewsBlurAppDelegate.h index 3d30af826..67145adf3 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.h +++ b/clients/ios/Classes/NewsBlurAppDelegate.h @@ -264,6 +264,7 @@ SFSafariViewControllerDelegate> { - (void)showFirstTimeUser; - (void)showLogin; - (void)setupReachability; +- (void)registerForRemoteNotifications; // social - (NSDictionary *)getUser:(NSInteger)userId; diff --git a/clients/ios/Classes/NewsBlurAppDelegate.m b/clients/ios/Classes/NewsBlurAppDelegate.m index 7933b5e68..86d5b1856 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.m +++ b/clients/ios/Classes/NewsBlurAppDelegate.m @@ -65,8 +65,9 @@ #import "UISearchBar+Field.h" #import "UIViewController+HidePopover.h" #import +#import -@interface NewsBlurAppDelegate () +@interface NewsBlurAppDelegate () @property (nonatomic, strong) NSString *cachedURL; @property (nonatomic, strong) UIApplicationShortcutItem *launchedShortcutItem; @@ -332,6 +333,62 @@ [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; } +- (void)registerForRemoteNotifications { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + center.delegate = self; + [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){ + if(!error){ + [[UIApplication sharedApplication] registerForRemoteNotifications]; + } + }]; +} + +//Called when a notification is delivered to a foreground app. +-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{ + NSLog(@"User Info : %@",notification.request.content.userInfo); + completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); +} + +//Called to let your app know which action was selected by the user for a given notification. +-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{ + NSLog(@"User Info : %@",response.notification.request.content.userInfo); + completionHandler(); +} + +-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + const char *data = [deviceToken bytes]; + NSMutableString *token = [NSMutableString string]; + + for (NSUInteger i = 0; i < [deviceToken length]; i++) { + [token appendFormat:@"%02.2hhX", data[i]]; + } + + NSLog(@" -> APNS token: %@", token); + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/notifications/set_apns_token/", + self.url]]; + ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:url]; + __weak ASIHTTPRequest *request = _request; + [request setValidatesSecureCertificate:NO]; + [request setResponseEncoding:NSUTF8StringEncoding]; + [request setDefaultResponseEncoding:NSUTF8StringEncoding]; + [request setFailedBlock:^(void) { + NSLog(@"Failed to set APNS token"); + }]; + [request setCompletionBlock:^(void) { + NSString *responseString = [request responseString]; + NSData *responseData=[responseString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error; + NSDictionary *results = [NSJSONSerialization + JSONObjectWithData:responseData + options:kNilOptions + error:&error]; + NSLog(@" -> APNS: %@/%@", results, error); + }]; + [request setTimeOutSeconds:30]; + [request startAsynchronous]; + +} + - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication diff --git a/clients/ios/Classes/NewsBlurViewController.m b/clients/ios/Classes/NewsBlurViewController.m index 994923e56..60d0423a3 100644 --- a/clients/ios/Classes/NewsBlurViewController.m +++ b/clients/ios/Classes/NewsBlurViewController.m @@ -714,32 +714,6 @@ static UIFont *userLabelFont; appDelegate.categoryFeeds = [[results objectForKey:@"categories"] objectForKey:@"feeds"]; } - // test for latest version of app - NSString *serveriPhoneBuild = [results objectForKey:@"latest_ios_build"]; - NSString *currentiPhoneBuild = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey]; - NSString *serveriPhoneVersion = [results objectForKey:@"latest_ios_version"]; - NSString *currentiPhoneVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; - BOOL unseenBuild = [serveriPhoneBuild integerValue] > [userPreferences integerForKey:@"last_seen_latest_ios_build"]; - - if ([currentiPhoneBuild integerValue] < [serveriPhoneBuild integerValue] && unseenBuild) { - NSLog(@"Build: %ld - %@ (seen: %ld)", (long)[serveriPhoneBuild integerValue], currentiPhoneBuild, (long)[userPreferences integerForKey:@"last_seen_latest_ios_build"]); - [userPreferences setInteger:[serveriPhoneBuild integerValue] forKey:@"last_seen_latest_ios_build"]; - [userPreferences setObject:serveriPhoneVersion forKey:@"last_seen_latest_ios_version"]; - [userPreferences synchronize]; - - NSString *title = [NSString stringWithFormat:@ - "You should download the new version of NewsBlur.\n\nNew version: v%@\nYou have: v%@", - serveriPhoneVersion, - currentiPhoneVersion]; - UIAlertView *upgradeConfirm = [[UIAlertView alloc] initWithTitle:title - message:nil - delegate:self - cancelButtonTitle:@"Cancel" - otherButtonTitles:@"Upgrade!", nil]; - [upgradeConfirm show]; - [upgradeConfirm setTag:2]; - } - if (!self.isOffline) { // start up the first time user experience if ([[results objectForKey:@"social_feeds"] count] == 0 && @@ -767,6 +741,7 @@ static UIFont *userLabelFont; [self showExplainerOnEmptyFeedlist]; [self layoutHeaderCounts:0]; [self refreshHeaderCounts]; + [self checkForFeedNotifications]; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && finished) { [appDelegate.dashboardViewController refreshStories]; @@ -775,27 +750,6 @@ static UIFont *userLabelFont; [[NSNotificationCenter defaultCenter] postNotificationName:@"FinishedLoadingFeedsNotification" object:nil]; } -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if (alertView.tag == 2) { - if (buttonIndex == 0) { - return; - } else { - NSURL *url; - NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; - NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults]; - NSString *serverVersion = [userPreferences stringForKey:@"last_seen_latest_ios_version"]; - - if ([currentVersion containsString:@"b"] && [serverVersion containsString:@"b"]) { - url = [NSURL URLWithString:@"https://www.newsblur.com/ios/download"]; - } else { - // this doesn't work in simulator!!! because simulator has no app store - url = [NSURL URLWithString:@"itms://itunes.apple.com/us/app/mensa-essen/id463981119?ls=1&mt=8"]; - } - [[UIApplication sharedApplication] openURL:url]; - } - } -} - - (void)loadOfflineFeeds:(BOOL)failed { __block __typeof__(self) _self = self; self.isOffline = YES; @@ -2080,6 +2034,20 @@ heightForHeaderInSection:(NSInteger)section { userInfoBarButton, nil]; } +- (void)checkForFeedNotifications { + for (NSDictionary *feed in appDelegate.dictFeeds.allValues) { + NSArray *types = [feed objectForKey:@"notification_types"]; + if (types) { + for (NSString *notificationType in types) { + if ([notificationType isEqualToString:@"ios"]) { + [appDelegate registerForRemoteNotifications]; + return; + } + } + } + } +} + - (void)refreshHeaderCounts { if (!appDelegate.activeUsername) { userAvatarButton.customView.hidden = YES; diff --git a/clients/ios/NewsBlur.xcodeproj/project.pbxproj b/clients/ios/NewsBlur.xcodeproj/project.pbxproj index 8482053c2..3e8d9bcd8 100755 --- a/clients/ios/NewsBlur.xcodeproj/project.pbxproj +++ b/clients/ios/NewsBlur.xcodeproj/project.pbxproj @@ -1074,6 +1074,7 @@ FF793E1813F1A9F700F282D2 /* ASIDataCompressor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIDataCompressor.m; sourceTree = ""; }; FF793E1913F1A9F700F282D2 /* ASIDataDecompressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIDataDecompressor.h; sourceTree = ""; }; FF793E1A13F1A9F700F282D2 /* ASIDataDecompressor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIDataDecompressor.m; sourceTree = ""; }; + FF81FB1C1DDE9BF9003FA6B8 /* NewsBlur.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NewsBlur.entitlements; path = NewsBlur/NewsBlur.entitlements; sourceTree = ""; }; FF8364B91755759A008F5C58 /* traverse_text.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = traverse_text.png; sourceTree = ""; }; FF8364BA1755759A008F5C58 /* traverse_text@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "traverse_text@2x.png"; sourceTree = ""; }; FF8364BD1756949E008F5C58 /* traverse_text_on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = traverse_text_on.png; sourceTree = ""; }; @@ -1401,6 +1402,7 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + FF81FB1C1DDE9BF9003FA6B8 /* NewsBlur.entitlements */, 080E96DDFE201D6D7F000001 /* Classes */, 4307BE511565EDF8007A932A /* Resources */, 43D0451C1565BC090085F811 /* Resources-iPad */, @@ -2437,6 +2439,11 @@ 1D6058900D05DD3D006BFB54 = { DevelopmentTeam = HR7P97SD72; ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Push = { + enabled = 1; + }; + }; }; }; }; @@ -3050,6 +3057,7 @@ ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_OBJC_ARC = YES; + CODE_SIGN_ENTITLEMENTS = NewsBlur/NewsBlur.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -3067,7 +3075,7 @@ GCC_VERSION = ""; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = "NewsBlur-iPhone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", @@ -3095,6 +3103,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_OBJC_ARC = YES; + CODE_SIGN_ENTITLEMENTS = NewsBlur/NewsBlur.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -3111,7 +3120,7 @@ GCC_VERSION = ""; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = "NewsBlur-iPhone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"",