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;
}
Related
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:#"¤tMode=%#", [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?
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.
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.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Works in all cases except, when the App was running in the background and then launched by the user clicking on the notification, the app starts, the notification is shown with, but the clear doesn't work!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *notificationPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(notificationPayload) {
[self application:application didReceiveRemoteNotification:notificationPayload];
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if([[userInfo valueForKey:#"aps"] valueForKey:#"alert"] != nil) {
NSString *message = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
if(message != nil) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Usage Alert"
message:message delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alertView show];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
}
}
I'ld love to use this combination of Software for some simple push notifications.
Sending and Receiving isn't the problem - did it!
But how can I tell the jQueryMobile Application out of iOS that it is launched by PushNotification and shouldn't show the home screen but an other - notification related - screen instead?
Notification object has a property applicationLaunchNotification which has value 1 if the application is launched via the notifictaion.
This below method queries the pending notification on the start of the application:
window.plugins.pushNotification.getPendingNotifications(function(notifications) {
if(notifications.length > 0){
var note = notifications[0];
if(note.applicationLaunchNotification == "1"){
// do the processing
}
}
});
For detail - https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification
use can change you app deligate code and enable push in application pro-vising profile
#import "AppDelegate.h"
#import "MainViewController.h"
#import <Cordova/CDVPlugin.h>
#implementation AppDelegate
#synthesize window, viewController;
- (id)init
{
/** If you need to do any extra app-specific initialization, you can do it here
* -jm
**/
NSHTTPCookieStorage* cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
self = [super init];
return self;
}
#pragma mark UIApplicationDelegate implementation
/**
* This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up)
*/
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
self.window.autoresizesSubviews = YES;
self.viewController = [[[MainViewController alloc] init] autorelease];
self.viewController.useSplashScreen = YES;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
// this happens while we are running ( in the background, or from within our own app )
// only valid if __TESTING__-Info.plist specifies a protocol to handle
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url
{
if (!url) {
return NO;
}
// calls into javascript global function 'handleOpenURL'
NSString* jsString = [NSString stringWithFormat:#"handleOpenURL(\"%#\");", url];
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString];
// all plugins will get the notification, and their handlers will be called
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
return YES;
}
// repost the localnotification using the default NSNotificationCenter so multiple plugins may respond
// ADD OUR NOTIFICATION CODE
#pragma mark - Push notification Delegate Methods
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
//NSLog(#"content---%#", token);
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
//flagPushConfirmation=[NSString stringWithFormat:#"startPush"];
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Device not Register for notification"
delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil];
[message show];
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Notification"
message:#"Recieve Notification" delegate:self cancelButtonTitle:#"cancel"otherButtonTitles:#"ok",nil];
[message show];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
// WAS RUNNING
NSLog(#"I was currently active");
NSString *notCB = [notification.userInfo objectForKey:#"foreground"];
NSString *notID = [notification.userInfo objectForKey:#"notificationId"];
NSString * jsCallBack = [NSString
stringWithFormat:#"%#(%#)", notCB,notID];
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
application.applicationIconBadgeNumber = 0;
}
else {
// WAS IN BG
NSLog(#"I was in the background");
NSString *notCB = [notification.userInfo objectForKey:#"background"];
NSString *notID = [notification.userInfo objectForKey:#"notificationId"];
NSString * jsCallBack = [NSString
stringWithFormat:#"%#(%#)", notCB,notID];
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
application.applicationIconBadgeNumber = 0;
}
}
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
// iPhone doesn't support upside down by default, while the iPad does. Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected).
NSUInteger supportedInterfaceOrientations = (1 << UIInterfaceOrientationPortrait) | (1 << UIInterfaceOrientationLandscapeLeft) | (1 << UIInterfaceOrientationLandscapeRight) | (1 << UIInterfaceOrientationPortraitUpsideDown);
return supportedInterfaceOrientations;
}