Receiving push notification with Rover iOS 11 - ios

The iOS app I have been hired to build uses Batch and Rover. While I have had success in getting Batch to display an incoming notification, Rover is not even attempting to connect. I've been trying to figure this problem out for a few hours now. Here is my AppDelegate:
#import Batch;
#import Rover;
#import "app_appDelegate.h"
#import "BT_loading.h"
#implementation app_appDelegate
//didFinishLaunchingWithOptions...
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[BT_debugger showIt:self message:[NSString stringWithFormat:#"didFinishLaunchingWithOptions (iOS)%#", #""]];
[Batch startWithAPIKey:#"_removed_"];
[BatchPush registerForRemoteNotifications];
[Rover setupWithApplicationToken:#"_removed_"];
[Rover registerForNotifications];
[Rover startMonitoring];
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
// notificationPayload = #{#"nickname":#"Wine List 1"};
[self appOpenDeepLink:notificationPayload];
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
if (application.applicationState != UIApplicationStateBackground) {
// Track an app open here if we launch with a push, unless
// "content_available" was used to trigger a background push (introduced
// in iOS 7). In that case, we skip tracking here to avoid double
// counting the app-open.
BOOL preBackgroundPush = ![application respondsToSelector:#selector(backgroundRefreshStatus)];
BOOL oldPushHandlerOnly = ![self respondsToSelector:#selector(application:didReceiveRemoteNotification:fetchCompletionHandler: self: showDeepLinkScreen:userInfo:)];
BOOL noPushPayload = ![launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (preBackgroundPush || oldPushHandlerOnly || noPushPayload) {
//[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
}
}
}
NSLog(#"Notification Payload: %#", notificationPayload);
//hide status bar on launch...
[[UIApplication sharedApplication] setStatusBarHidden:TRUE withAnimation:UIStatusBarAnimationNone];
//setup the window on launch...
[self setWindow:[[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]];
[self.window setBackgroundColor:[BT_color getColorFromHexString:#"#FFFFFF"]];
//load initial storyboard, "BT_loading"...
UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:#"BT_loading" bundle:nil];
BT_viewController *launchViewController = [launchStoryboard instantiateViewControllerWithIdentifier:#"BT_loading"];
//set the rootViewController on the window to the BT_loading storyboard...
self.window.rootViewController = launchViewController;
[self.window makeKeyAndVisible];
//return...
return TRUE;
}
- (void) appOpenDeepLink:(NSDictionary *) notificationPayload{
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"screenNickname"];
if(notificationPayload[#"nickname"]){
[[NSUserDefaults standardUserDefaults] setObject:notificationPayload[#"nickname"] forKey:#"screenNickname"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
//when app becomes active again
- (void)applicationDidBecomeActive:(UIApplication *)application{
//make sure we have an app...
if([self rootApp] == nil){
[BT_debugger showIt:self message:[NSString stringWithFormat:#"applicationDidBecomeActive rootApp not available yet (iOS).%#", #""]];
}else{
[BT_debugger showIt:self message:[NSString stringWithFormat:#"applicationDidBecomeActive (iOS)%#", #""]];
//flag as visible...
[self setUiIsVisible:TRUE];
//report to cloud (not all apps do this, dataURL and reportToCloudURL required)...
if([[self.rootApp dataURL] length] > 1 && [[self.rootApp reportToCloudURL] length] > 1){
if(![self isRefreshing]){
[self reportToCloud];
}
}
//if we have a location manager...
if([self rootLocationManager] != nil){
[self.rootLocationManager setUpdateCount:0];
[self.rootLocationManager.locationManager startUpdatingLocation];
}
}
}
//promptforPushNotificationsAfterDelay...
-(void)promptforPushNotificationsAfterDelay{
[BT_debugger showIt:self message:[NSString stringWithFormat:#"promptforPushNotificationsAfterDelay%#", #""]];
if([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)]){
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
//didRegisterForRemoteNotificationsWithDeviceToken...
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
[Rover didRegisterForRemoteNotificationWithDeviceToken:deviceToken];
[BT_debugger showIt:self theMessage:[NSString stringWithFormat:#"didRegisterForRemoteNotificationsWithDeviceToken (iOS): Device Token: %#", deviceToken]];
//if we have a token, and a register it...
if([deviceToken length] > 1 && [[self.rootApp registerForPushURL] length] > 1){
//clean up token...
NSString *useToken = [NSString stringWithFormat:#"%#", deviceToken];
useToken = [useToken stringByReplacingOccurrencesOfString:#"<"withString:#""];
useToken = [useToken stringByReplacingOccurrencesOfString:#">"withString:#""];
useToken = [useToken stringByReplacingOccurrencesOfString:#" "withString:#""];
//save it for next time...
[BT_strings setPrefString:#"lastDeviceToken" valueOfPref:useToken];
//append deviceToken and deviceType to end of URL...
NSString *useURL = [[self.rootApp registerForPushURL] stringByAppendingString:[NSString stringWithFormat:#"&deviceType=%#", #"ios"]];
useURL = [useURL stringByAppendingString:[NSString stringWithFormat:#"&deviceToken=%#", useToken]];
//append currentMode ("Live" or "Design") to end of URL...
useURL = [useURL stringByAppendingString:[NSString stringWithFormat:#"&currentMode=%#", [self currentMode]]];
//merge environment variables in URL...
useURL = [BT_strings mergeBTVariablesInString:useURL];
//escape the URL...
NSString *escapedUrl = [useURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//tell the BT_device to register on the server (the device class makes the URL request)...
[appDelegate.rootDevice registerForPushNotifications:escapedUrl];
}
}
//didFailToRegisterForRemoteNotificationsWithError...
-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{
[BT_debugger showIt:self theMessage:[NSString stringWithFormat:#"didFailToRegisterForRemoteNotificationsWithError (iOS): ERROR: %#", error]];
}
//didReceiveRemoteNotification..
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
[BT_debugger showIt:self theMessage:[NSString stringWithFormat:#"didReceiveRemoteNotification (iOS)%#", #""]];
//NSLog(#"Message ID: %#", userInfo);
//NSLog(#"%#", userInfo);
//(void)[Rover didReceiveRemoteNotification:userInfo fetchCompletionHandler:nil];
//don't do anything if the app is not in the foreground. iOS handles inbound APNS message when app is in the background...
if(application.applicationState == UIApplicationStateActive){
NSString *alertMsg;
NSString *badge;
NSString *sound;
//alert message...
if([[userInfo objectForKey:#"aps"] objectForKey:#"alert"] != NULL){
alertMsg = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
}
//badge...
if([[userInfo objectForKey:#"aps"] objectForKey:#"badge"] != NULL){
badge = [[userInfo objectForKey:#"aps"] objectForKey:#"badge"];
}
//sound...
if([[userInfo objectForKey:#"aps"] objectForKey:#"sound"] != NULL){
sound = [[userInfo objectForKey:#"aps"] objectForKey:#"sound"];
}
//if we have a sound...
if([sound length] > 1){
[self performSelector:#selector(playSoundFromPushMessage:) withObject:sound afterDelay:.1];
}
//show messsage...
//UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"" message:alertMsg preferredStyle:UIAlertControllerStyleAlert];
//UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *alertTag)
// {
// OK button tappped.
//[self dismissViewControllerAnimated:YES completion:^{
//}];
// }];
// [alert addAction:MyAlert];
//[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:YES completion:nil];
//show messsage...
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"" message:alertMsg delegate:nil cancelButtonTitle:NSLocalizedString(#"ok", "OK") otherButtonTitles:nil];
[alert show];
////WATCH
}//in foreground...
}
//playSoundFromPushMessage...
-(void)playSoundFromPushMessage:(NSString *)soundEffectFileName{
[BT_debugger showIt:self theMessage:[NSString stringWithFormat:#"playSoundFromPushMessage: %#", soundEffectFileName]];
NSString *theFileName = soundEffectFileName;
if([BT_fileManager doesFileExistInBundle:theFileName]){
NSURL *soundFileUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], theFileName]];
NSError *error;
AVAudioPlayer *tmpPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileUrl error:&error];
if(!error){
[tmpPlayer setNumberOfLoops:0];
[tmpPlayer prepareToPlay];
[tmpPlayer play];
}else{
[BT_debugger showIt:self theMessage:[NSString stringWithFormat:#"didReceiveRemoteNotification soundEffectPlayer ERROR: %#", [error description]]];
}
}
}
//playSoundEffect...
-(void)playSoundEffect:(NSString *)theFileName{
[BT_debugger showIt:self message:[NSString stringWithFormat:#"playSoundEffect %#", theFileName]];
if([theFileName length] > 3){
if([self.rootSoundEffectPlayer.soundEffectNames containsObject:theFileName]){
int playerIndex = (int)[self.rootSoundEffectPlayer.soundEffectNames indexOfObject:theFileName];
AVAudioPlayer *tmpPlayer = (AVAudioPlayer *)[self.rootSoundEffectPlayer.soundEffectPlayers objectAtIndex:playerIndex];
if(tmpPlayer){
[tmpPlayer play];
}
}else{
[BT_debugger showIt:self message:[NSString stringWithFormat:#"playSoundInBundle:ERROR. This sound effect is not included in the list of available sounds: %#", theFileName]];
}
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(#"Message ID: %#", userInfo);
NSLog(#"%#", userInfo);
(void)[Rover didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
#end
I have been going off the instruction created by the Rover developers at: https://github.com/RoverPlatform/rover-ios
I'm probably missing something simple but guidance would definitely be appreciated.
My logcat's responses to Rover:
Rover [4] - [LocationManager.swift.startMonitoring() - Line 76] => Monitoring started.
Rover [4] - [EventOperation.swift.execute() - Line 106] => Submitting event - applicationOpen(2018-02-28 07:46:02 +0000)
Rover [4] - [BluetoothStatusOperation.swift.execute() - Line 34] => Checking Bluetooth status
Rover [4] - [BluetoothStatusOperation.swift.centralManagerDidUpdateState - Line 48] => Determined Bluetooth status - true
Rover [4] - [LocationManager.swift.locationManager(_:didUpdateLocations:) - Line 114] => Received location update.
Rover [0] - [NetworkOperation.swift.execute() - Line 108] => Client error
Rover [4] - [EventOperation.swift.execute() - Line 106] => Submitting event
Rover [0] - [NetworkOperation.swift.execute() - Line 108] => Client error
2018-02-28 02:46:03.792824-0500 app[1540:560757] [CoreBluetooth] XPC connection invalid

If you put a breakpoint on the [Rover startMonitoring]; what happens?
Does rover require you to pass it your APNS token to work?

Related

Not Receiving Push Notification in IOS 10.3.1 and Receiving twice in ios 9

I am using Version 8.2.1. The Issue is I am not getting notifications in IOS 10.3.1 but I am getting notifications in IOS 9(but twice).
Here is my code which I tried :
//In **didFinishLaunchingWithOptions**
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
if( SYSTEM_VERSION_LESS_THAN( #"10.0" ) )
{
if ([application respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
// iOS 8 Notifications
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
}
}
else
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) compl
etionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error )
{
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog( #"Push registration success." );
}
else
{
NSLog( #"Push registration FAILED" );
NSLog( #"ERROR: %# - %#", error.localizedFailureReason, error.localizedDescription );
NSLog( #"SUGGESTIONS: %# - %#", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
if([self pushNotificationOnOrOff]) {
NSLog(#"Push Notification is ON!");
} else {
NSLog(#"Push Notification is OFF.");
}
if (launchOptions != nil)
{
NSDictionary* dictionary1 = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary1 != nil)
{
//RemoteNotification Payload
NSLog(#"Launched from push notification: %#", dictionary1);
Globals.instance.isNotification = TRUE;
NSString* iUUID = [[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey] objectForKey:#"UUID"];
[self.window makeKeyAndVisible];
NSDictionary* dictData = [Database getDataForUUID:iUUID];
if (dictData){
//Show dictData
}
}
}
**// Push Notification Receiving Methods**
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
NSString* deviceTokenStr = [NSString stringWithFormat:#"%#", deviceToken];
deviceTokenStr = [deviceTokenStr substringWithRange:NSMakeRange(1, deviceTokenStr.length-2)];
if (!Globals.instance.deviceToken) {
Globals.instance.deviceToken = deviceTokenStr;
}
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
NSLog(#"Failed to get token, error: %#", error);
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)notification {
NSDictionary* data = [self checkForData:notification];
if (data){
if (application.applicationState == UIApplicationStateActive) [self activeAlertForData: data];
else [self displayData: data];
}
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
NSLog(#"Userinfo %#",notification.request.content.userInfo);
completionHandler(UNNotificationPresentationOptionAlert);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler {
NSLog(#"Userinfo %#",response.notification.request.content.userInfo);
}
-(BOOL)pushNotificationOnOrOff
{
BOOL pushEnabled=NO;
if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
pushEnabled=YES;
} else {
pushEnabled=NO;
}
return pushEnabled;
}
- (NSDictionary*)checkForData:(NSDictionary*)notification {
NSString* iUUID = [notification objectForKey:#"UUID"];
NSDictionary* dict = [Database getUUID:iUUID];
NSString* alertData = [notification objectForKey:#"alert"];
return dict;
}
- (void)activeAlertForData:(Inc*)inc {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"New Post”
message:inc.description
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#“Open”
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// Jump to Post.
}];
[alert addAction:yesButton];
[alert addAction:noButton];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
});
}
Please guide me to resolve this issue.
Thanks in Advance.

After removing alert view from didReceiveLocalNotification in active state,no notification is coming in foreground

I'm implementing local notifications,there are 3 notifications to be send at different times of a day.
in my app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
}
and in DidReceiveLocalNotifications
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSString *checkbtn= [[NSUserDefaults standardUserDefaults]valueForKey:#"on"];
if([checkbtn isEqualToString:#"SwitchOn"])
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Green Actions"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
//}
}
if i remove this alert view,i m not getting any notification in foreground but if i use this then i m getting notification alert every second.
this is my viewcontroller code
- (void)viewDidLoad {
[super viewDidLoad];
appdelegate= (AppDelegate *) [[UIApplication sharedApplication]delegate];
[self createCustomeNavigationBar];
self.navigationController.navigationBar.translucent = NO;
//[self notificationOne];
[self.switchbutton addTarget:self action:#selector(switchToggled:) forControlEvents:UIControlEventValueChanged];
[self.switchbutton1 addTarget:self action:#selector(switchToggled1:) forControlEvents:UIControlEventValueChanged];
[self.switchbutton3 addTarget:self action:#selector(switchToggled3:) forControlEvents:UIControlEventValueChanged];
if ([[NSUserDefaults standardUserDefaults]valueForKey:#"on"])
{
UILocalNotification* n1 = [[UILocalNotification alloc] init];
n1.fireDate = [NSDate dateWithTimeIntervalSinceNow: 160];
n1.alertBody = #"one";
[[UIApplication sharedApplication] scheduleLocalNotification: n1];
}
if ([[NSUserDefaults standardUserDefaults]valueForKey:#"SwitchOneon"])
{
UILocalNotification* n2 = [[UILocalNotification alloc] init];
n2.fireDate = [NSDate dateWithTimeIntervalSinceNow: 190];
n2.alertBody = #"two";
[[UIApplication sharedApplication] scheduleLocalNotification: n2];
}
// Do any additional setup after loading the view from its nib.
}
- (void) switchToggled:(id)sender {
self.switchbutton = (UISwitch *)sender;
if ([self.switchbutton isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"on"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"on"];
NSLog(#"its off!");
}
}
- (void) switchToggled1:(id)sender {
self.switchbutton1 = (UISwitch *)sender;
if ([self.switchbutton1 isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"SwitchOneon"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"SwitchOneon"];
NSLog(#"its off!");
}
}
- (void) switchToggled3:(id)sender {
self.switchbutton3 = (UISwitch *)sender;
if ([self.switchbutton3 isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"SwitchThreeon"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"SwitchThreeon"];
NSLog(#"its off!");
}
}
and also i m getting some different text in alert view which i used earlier just for testing purpose,even after changing it,i m getting the same old previous text.
I am sure that problem isn't with alert code. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification, you're getting notification. But when your app is in foreground (or active) you should handle it manually. In your case, you're handling it with UIAlertView so it will be visible in alert, but once you removed, you're not able to see a notification when your app was in foreground (or active) state.

Displaying alert from app delegate before displaying alert from viewDidload

I am attempting to display the message contained within a push notification through the app delegate as outlined in the parse.com documentation.
The problem I am having is that in my viewdidload method for my first view controller, i am presenting an alert which the user MUST see before they use the app.
How can I call the method from my app delegate after the user sees the Alert from the viewdidload method?
EDIT:
So i have, as suggested in the comments, added a global Variable which i set to true once i have Displayed the alert from my ViewDidload method, but the Notification Alert from my appDelegate still does not appear.
here is my app delegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[Parse setApplicationId:#"xxxxxxxxxxxxxxxx"
clientKey:#"xxxxxxxxxxxx"];
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
return YES;
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (Notification == true) {
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
And here is my viewdidload method:
RoadSafetyAppAppDelegate *AppDelegate;
- (void)viewDidLoad
{
AppDelegate = (RoadSafetyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
backgroundImage.alpha = 0.3;
toRecipients = [[NSArray alloc]initWithObjects:#"records#shellharbour.nsw.gov.au", nil];
static int appCounter;
if ( appCounter < 1 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
[alert show];
appCounter = appCounter+1;
AppDelegate.NotificationAlert = #"1";
AppDelegate.Notification = true;
}
}
since you want to show the disclaimer ONE time and to be sure that the user saw it and TAPED on Agree Button before showing any notification. you can do that using a simple local notification.
in delegate (...didFinishLaunchingWithOptions:)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==nil)
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]){ //YES
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSString *value=[NSString stringWithFormat:#"%#",[notification.userInfo valueForKey:#"key"]];
if ([value isEqualToString:#"disclaimerShown"]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
///continue handle parse.com notification
}
}
in you ViewController:
-(void)viewDidLoad{
//...
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==NO){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
alert.tag = 1;
[alert show];
}
//...
}
pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1) {//the disclaimer alert
if (buttonIndex == 0) {
UILocalNotification *alarm = [[UILocalNotification alloc] init];
alarm.userInfo = #{#"key": #"disclaimerShown"};
alarm.fireDate = [NSDate date];
alarm.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
}
}
}
Instead of AppDelegate bool flag property use NSUserDefaults;
In AppDelegate update this line from:
if (Notification == true)
to
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Notification"] == YES)
And in ViewController -> viewDidLoad method update line from:
AppDelegate.Notification = true;
to
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Notification"];
[[NSUserDefaults standardUserDefaults] synchronize];
Hope this helps.

after agreeing to receive push-notification the app crashes iphone

notification for my app, and i couldn't figure out, why the app crashes after the push-notification dialog. If I run the app again after the crash it will work fine, and the token will be registered in my DB
Would really appreciate your help with this problem.
Thanks in advance
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self registerPushNotification];
//[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
//[self loadQuestionsAnswersFromPlist];
[Tapjoy requestTapjoyConnect:#"xxx" secretKey:#"xx" options:#{ TJC_OPTION_ENABLE_LOGGING : #(YES) } ];
[NSThread sleepForTimeInterval:2.0f];
[self.window addSubview:_tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
-(void) registerPushNotification {
NSString *iOSversion = [[UIDevice currentDevice] systemVersion];
NSString *prefix = [[iOSversion componentsSeparatedByString:#"."] firstObject];
float versionVal = [prefix floatValue];
if (versionVal >= 8)
{
//for iOS8
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:#"declineAction"]){
}
else if ([identifier isEqualToString:#"answerAction"]){
}
}
#endif
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devviceToken
{
self.deviceToken = [[[devviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]] stringByReplacingOccurrencesOfString:#" " withString:#""];
SessionData* sData = [SessionData sharedManager];
sData.hasReceivedToken = TRUE;
sData.token = self.deviceToken;
if (sData.isRegistered) {
id<MyInfoViewDelegate> myInfoVC = [[_tabBarController viewControllers] objectAtIndex:0];
[myInfoVC saveDeviceToken:self.deviceToken];
}
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (application.applicationState == UIApplicationStateInactive ||
application.applicationState == UIApplicationStateBackground) {
application.applicationIconBadgeNumber = 0;
}
NSDictionary* keys = [userInfo objectForKey:#"aps"];
NSString* alert = [keys objectForKey:#"alert"];
int code = [[keys objectForKey:#"code"]intValue];
if (code == 1) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"New Question" message:alert delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
}
}
log
2014-10-07 07:26:13.603 Health Screener[145:60b] starting profile
request using - 2.1.17 with options: 63 2014-10-07 07:26:14.486 Health
Screener[145:60b] [TJLog level: 4] Tapjoy Request:
https://connect.tapjoy.com/connect?
2014-10-07 07:26:16.821 Health Screener[145:60b] Application windows
are expected to have a root view controller at the end of application
launch 2014-10-07 07:26:17.930 Health Screener[145:60b] [TJLog level:
4] Connect success with type:0 2014-10-07 07:26:18.197 Health
Screener[145:60b]
{"success":true,"output":{"success":true,"userid":1284,"udid":
2014-10-07 07:26:19.988 Health Screener[145:60b] [TJLog level: 4]
Events proxy is ready 2014-10-07 07:26:21.178 Health Screener[145:60b]
-[UINavigationController saveDeviceToken:]: unrecognized selector sent to instance 0x17565670 2014-10-07 07:26:21.181 Health
Screener[145:60b] * Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UINavigationController
saveDeviceToken:]: unrecognized selector sent to instance 0x17565670'
* First throw call stack: (0x2d7eaf83 0x37f9bccf 0x2d7ee917 0x2d7ed203 0x2d73c768 0x343c7 0x30329867 0x3032a3d5 0x3119df2f
0x2d7b5a67 0x2d7b5a03 0x2d7b41d7 0x2d71eebf 0x2d71eca3 0x32624663
0x3006b14d 0x337ed 0x384a8ab7) libc++abi.dylib: terminating with
uncaught exception of type NSException
// savedevicetoken
-(void)saveDeviceToken:(NSString*) deviceToken{
self.api.requestCode = 5; NSString *baseURL = [BASE_URL stringByAppendingString:SAVE_DEVICE_TOKEN];
SessionData *sData = [SessionData sharedManager];
NSMutableString *parameters = [NSMutableString string]; [parameters appendFormat:#"uid=%d",sData.userId]; [parameters
appendFormat:#"&token=%#",deviceToken]; NSLog(#"%#",parameters);
[self.api httpPost:baseURL withRequest:parameters]; }
-(void)didFinishRequest {
NSError *e = nil;
NSDictionary *output = [NSJSONSerialization JSONObjectWithData: [self.api.message dataUsingEncoding:NSUTF8StringEncoding] options:
NSJSONReadingMutableContainers error: &e];
BOOL success = [[output objectForKey:#"success"] boolValue];
if (self.api.requestCode == 1) {
if (success) {
SessionData *sData = [SessionData sharedManager];
sData.userId = [[[output objectForKey:#"output"] objectForKey:#"userid"] intValue];
sData.isRegistered = YES;
if (sData.hasReceivedToken) {
sData.callGetAnswers = YES;
[self saveDeviceToken:sData.token];
} else {
[self getQuestionsAndAnswers];
}
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"You do not have internet connection,
try again when you have an internet connection." delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
return;
}

Problems displaying UIAlertView from notification when app is closed

I have the following code that I use for push notifications:
located within my appdelegate.m is the following code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//Register to receive notifcations
//-- Set Notification
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
[Pushbots getInstance];
NSDictionary * userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo) {
// Notification Message
NSString* notificationMsg = [userInfo valueForKey:#"message"];
// Custom Field
NSString* title = [userInfo valueForKey:#"title"];
NSLog(#"Notification Msg is %# and Custom field title = %#", notificationMsg , title);
}
return YES;
}
-(void)onReceivePushNotification:(NSDictionary *) pushDict andPayload:(NSDictionary *)payload {
[payload valueForKey:#"title"];
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"New Alert !" message:[pushDict valueForKey:#"alert"] delegate:self cancelButtonTitle:#"Thanks !" otherButtonTitles: #"Open",nil];
[message show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Open"]) {
[[Pushbots getInstance] OpenedNotification];
// set Badge to 0
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
// reset badge on the server
[[Pushbots getInstance] resetBadgeCount];
}
}
This code works fine when the application is not closed, it presents me with the notification alert view.
HOWEVER it does not work properly when the application is closed fully and not running in background.
And I dont know what to do about it!
Thanks in advance?
you cannot since displaying an alert view required the notification invoking some part of your code, however the entry point for your code i.e. where you may first handle anything regarding your notification is on
(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary) launchOptions
which means your app has to be awake in order to show a custom alert view.
For now you will have to settle to the default implementation ios gives you, that is the notification bar at the top.
hope ts useful

Resources