Phonegap App with Urban Airship Problems - xcode

Im trying to integrate Push Notifications in my iOS App. This is a Phonegap/Cordova Project. Everything is working well, without the APNS and Urban Airship.
What I have done till now? I got it to work, that I could send a Push Message from UA to my phone, but that was done with sample code from different forums and not the UA docs. So I startet to do it like in the docs of UA is showed. With that Im very confused and tried a lot.
So i did following:Took the Push Sample from UA and copied the code to AppDelegate.m what looks now like this:
// Create Airship singleton that's used to talk to Urban Airhship servers.
// Please populate AirshipConfig.plist with your info from http://go.urbanairship.com
[UAirship takeOff:takeOffOptions];
[[UAPush shared] resetBadge];//zero badge on startup
[[UAPush shared] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
UALOG(#"Application did become active.");
[[UAPush shared] resetBadge]; //zero badge when resuming from background (iOS 4+)
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
UALOG(#"APN device token: %#", deviceToken);
// Updates the device token and registers the token with UA
[[UAPush shared] registerDeviceToken:deviceToken];
/*
* Some example cases where user notification may be warranted
*
* This code will alert users who try to enable notifications
* from the settings screen, but cannot do so because
* notications are disabled in some capacity through the settings
* app.
*
*/
/*
//Do something when notifications are disabled altogther
if ([application enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone) {
UALOG(#"iOS Registered a device token, but nothing is enabled!");
//only alert if this is the first registration, or if push has just been
//re-enabled
if ([UAirship shared].deviceToken != nil) { //already been set this session
NSString* okStr = #"OK";
NSString* errorMessage =
#"Unable to turn on notifications. Use the \"Settings\" app to enable notifications.";
NSString *errorTitle = #"Error";
UIAlertView *someError = [[UIAlertView alloc] initWithTitle:errorTitle
message:errorMessage
delegate:nil
cancelButtonTitle:okStr
otherButtonTitles:nil];
[someError show];
[someError release];
}
//Do something when some notification types are disabled
} else if ([application enabledRemoteNotificationTypes] != [UAPush shared].notificationTypes) {
UALOG(#"Failed to register a device token with the requested services. Your notifications may be turned off.");
//only alert if this is the first registration, or if push has just been
//re-enabled
if ([UAirship shared].deviceToken != nil) { //already been set this session
UIRemoteNotificationType disabledTypes = [application enabledRemoteNotificationTypes] ^ [UAPush shared].notificationTypes;
NSString* okStr = #"OK";
NSString* errorMessage = [NSString stringWithFormat:#"Unable to turn on %#. Use the \"Settings\" app to enable these notifications.", [UAPush pushTypeString:disabledTypes]];
NSString *errorTitle = #"Error";
UIAlertView *someError = [[UIAlertView alloc] initWithTitle:errorTitle
message:errorMessage
delegate:nil
cancelButtonTitle:okStr
otherButtonTitles:nil];
[someError show];
[someError release];
}
}
*/
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error {
UALOG(#"Failed To Register For Remote Notifications With Error: %#", error);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UALOG(#"Received remote notification: %#", userInfo);
// Get application state for iOS4.x+ devices, otherwise assume active
UIApplicationState appState = UIApplicationStateActive;
if ([application respondsToSelector:#selector(applicationState)]) {
appState = application.applicationState;
}
[[UAPush shared] handleNotification:userInfo applicationState:appState];
[[UAPush shared] resetBadge]; // zero badge after push received
}
- (void)applicationWillTerminate:(UIApplication *)application {
[UAirship land];
}
Its pretty the same like before, but given from UA. Then i copied the files from the other sources folder from the Push Sample into my phonegap folder Supported Files including the AirshipConfig.plist. Also I set the Header Search Paths in the Build Settings to the Airship folder, what i copied before into the xCode project folder.
Now I get the error (6) "Use of undeclared identifier 'UAPush'" in the AppDeledate.m file. What can I do now?
Thanks for some help...

You need to import both UAirship.h & UAPush.h in your AppDelegate.m
#import "MainViewController.h"
#import "UAirship.h"
#import "UAPush.h"
This will get rid of your undeclared identifier issue. Silly Urban Airship forgot to put this in their Documentation

Have a look at Xtify push services, PhoneGap plugin is fully supported:
iOS:
http://developer.xtify.com/display/sdk/PhoneGap+for+iOS+Xtify+Integration+Guide
Android:
http://developer.xtify.com/display/sdk/PhoneGap+for+Android+Xtify+Integration+Guide

Related

NSSharingService performWithItems Hangs

I had a working share routine and now it is broken. Hadn't checked it, or modified it, for some time and now find that it is inoperable. When I call
[sharingService performWithItems:[NSArray arrayWithObject:itemProvider]];
I get a share sheet displayed. It shows the current members of the share. The form is inoperable and will not accept any input or taps. I cannot add, remove or stop sharing altogether. When I close the form, my app is hung up and will not respond or take focus. I have to kill the app and reopen to get it working again.
This used to work fine, within the last few months. I hadn't changed anything so I am very surprised by new problem.
I am adding my code for creating share here:
NSString *shareOption = [[NSUserDefaults standardUserDefaults] objectForKey:kSet_CLOUD_SERVICE_USER_DEFAULT];
if ([shareOption isEqualToString:TTICloudKitShareOwnerService]) {
CDEZipCloudFileSystem *zipFile = (CDEZipCloudFileSystem *)_cloudFileSystem;
CDECloudKitFileSystem *fileSystem = (CDECloudKitFileSystem *)zipFile.cloudFileSystem;
NSItemProvider *itemProvider = [[NSItemProvider alloc] init];
[itemProvider registerCloudKitShare:fileSystem.share container:fileSystem.container];
NSSharingService *sharingService = [NSSharingService sharingServiceNamed:NSSharingServiceNameCloudSharing];
sharingService.subject = #"Share Workforce Data";
sharingService.delegate = self;
if ([sharingService canPerformWithItems:[NSArray arrayWithObject:itemProvider]]) {
[sharingService performWithItems:[NSArray arrayWithObject:itemProvider]];
// This is the point at which the Apple UI is presented but inoperable.
// No changes can be made to the share.
// The only way to dismiss the dialog is to quit or press escape.
// Upon dismissal the app is either crashed or hung up.
// Quitting the app and restart is only option to use the app again.
// If not run from Xcode, requires force quit.
}
} else {
NSLog(#"Is Shared Ensemble");
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"Stop Share"];
[alert addButtonWithTitle:#"Cancel"];
[alert setMessageText:#"Shared Data Options"];
[alert setInformativeText:#"You are participating in a shared file. Stop sharing will remove your participation and reset your data. You will no longer participate or have access to the shared information."];
[alert setAlertStyle:NSAlertStyleWarning];
if ([alert runModal] == NSAlertFirstButtonReturn) {
[alert setInformativeText:#"Are you sure? You will no longer have access to shared data. You will need the owner of the share to resend an invitation to join the share."];
if ([alert runModal] == NSAlertFirstButtonReturn) {
// This actually does not remove user from sharing as intended.
// I am sure that is my own implementation incomplete though.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setNilValueForKey:kSet_CLOUDKIT_SHARE_OWNER_DEFAULT];
[defaults setObject:TTICloudKitShareOwnerService forKey:kSet_CLOUD_SERVICE_USER_DEFAULT];
[defaults synchronize];
[self disconnectFromSyncServiceWithCompletion:^{
// TODO: Need to wipe the existing Core Data info here. Leave them with no access to shared data.
// Also need to remove self from the share?
[self reset];
[self setupEnsemble];
}];
}
}
}
Creating share and sending worked flawlessly and I'd been developing app and testing live. Currently my test is shared with two other users and still works. In fact I can't seem to find a way to stop sharing with those users or in any way alter the current share at all.
This is the NSCloudSharingServiceDelegate code:
-(NSCloudKitSharingServiceOptions)optionsForSharingService:(NSSharingService *)cloudKitSharingService shareProvider:(NSItemProvider *)provider
{
return NSCloudKitSharingServiceAllowPrivate | NSCloudKitSharingServiceAllowReadWrite;
}
-(void)sharingService:(NSSharingService *)sharingService willShareItems:(NSArray *)items
{
DLog(#"Will Share Called with items:%#",items);
}
-(void)sharingService:(NSSharingService *)sharingService didShareItems:(NSArray *)items
{
DLog(#"Did share called");
}
-(void)sharingService:(NSSharingService *)sharingService didFailToShareItems:(NSArray *)items error:(NSError *)error
{
DLog(#"Sharing service failed to share items, %#-", error);
if (error.code == NSUserCancelledError) return;
DLog(#"Failed to share, error- %#", error.userInfo);
[self disconnectFromSyncServiceWithCompletion:^{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:kSet_CLOUDKIT_SHARE_OWNER_DEFAULT forKey:kSet_CLOUD_SERVICE_USER_DEFAULT];
[defaults setNilValueForKey:kSet_CLOUDKIT_SHARE_OWNER_DEFAULT];
[defaults synchronize];
}];
}
It is apparent that I am one of the very few who find this to be important as I have scoured the webs and found almost nobody discussing it. Apple documentation is just about nil.
This is a screenshot of the Apple UI which is not working:
I am posting this as an answer, is more like a work around that I have managed to get working. Still no answer as to why the Apple UI does not respond.
See code for inviting participants without the Apple UI.
-(void)addParticipantWithEmail:(NSString *)email toShare:(CKShare *)share inContainer:(CKContainer *)container
{
[container discoverUserIdentityWithEmailAddress:(email) completionHandler:^(CKUserIdentity * _Nullable userInfo, NSError * _Nullable error) {
if (!userInfo || error) {
NSLog(#"Participant was not found for email %#", email);
if (error) {
NSLog(#"Error: %#", error.userInfo);
} else {
NSLog(#"No error was provided");
}
// abort
return;
}
CKFetchShareMetadataOperation *fetchMetaDataOperation = [[CKFetchShareMetadataOperation alloc] initWithShareURLs:[NSArray arrayWithObject:share.URL]];
fetchMetaDataOperation.shouldFetchRootRecord = YES;
[fetchMetaDataOperation setPerShareMetadataBlock:^(NSURL * _Nonnull shareURL, CKShareMetadata * _Nullable shareMetadata, NSError * _Nullable error) {
CKRecord *root = shareMetadata.rootRecord;
if (!root) {
NSLog(#"There was an error retrieving the root record- %#", error);
} else {
NSLog(#"Root is %#", root);
NSLog(#"/n");
}
CKUserIdentityLookupInfo *info = userInfo.lookupInfo;
CKFetchShareParticipantsOperation *fetchOperation = [[CKFetchShareParticipantsOperation alloc] initWithUserIdentityLookupInfos:[NSArray arrayWithObject:info]];
[fetchOperation setShareParticipantFetchedBlock:^(CKShareParticipant * _Nonnull participant) {
participant.permission = CKShareParticipantPermissionReadWrite;
[share addParticipant:participant];
CKModifyRecordsOperation *modifyOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:[NSArray arrayWithObjects:root, share, nil] recordIDsToDelete:nil];
modifyOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged;
[modifyOperation setPerRecordCompletionBlock:^(CKRecord * _Nonnull record, NSError * _Nullable error) {
if (error) {
DLog(#"Error modifying record %#. UserInfo: %#", record, error.userInfo);
} else {
DLog(#"No Error Reported in Modify Operation");
}
}];
[container.privateCloudDatabase addOperation:modifyOperation];
}];
[fetchOperation setFetchShareParticipantsCompletionBlock:^(NSError * _Nullable operationError) {
if (operationError) {
NSLog(#"There was en error in the fetch operation- %#", operationError.userInfo);
// Error may be a network issue, should implement a retry and possibly a limit to how many times to run it
}
}];
[container addOperation:fetchOperation];
}];
[container addOperation:fetchMetaDataOperation];
}];
}
It seems now, if I pass an email address to this function they are successfully invited to share, provided the user is in my contacts and has allowed discoverability.
I send the user the link to the share manually via iMessage at this point. Copied the URL from the console. My intent is to provide my own forms to handle that now.
On receiving link, I use Ensembles method:
CDECloudKitFileSystem acceptInvitationToShareWithMetadata:metadata completion:^(NSError *error)
This code didn't seem to work, accepting invites was failing initially. Without having changed anything, the accepting shares started to work. I am not sure why the initial fails.

Clear badge icon using Parse

I am using Parse for push notifications.
When sending a push adding a badge icon is simply done by checking a check box on parse, no code implementation required.
Problem is I can't seem to find a solution in the documentation for clear the badges on once the app is launched .
Any input appreciated.
try this in your appdelegate.m:
- (void)applicationDidBecomeActive:(UIApplication *)application {
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
if (currentInstallation.badge != 0) {
currentInstallation.badge = 0;
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
// Handle error here with an alert…
}
else {
// only update locally if the remote update succeeded so they always match
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
}];
}
}
this should reset badge every time.

Receiving Apple Push Notifications when app is in background

I have implemented push notifications in my iOS8 app. I am trying to play an audio file once the notification is received.
The code is playing the audio when the app is in the foreground, but when the app is in the background, nothing happens.
I have tried regenerating the certificates and provisioning profiles. And I have made sure that the app is running in the background, i.e. the user has not swiped up to remove it. In Background modes, I have enabled Remote Notifications, Background Fetch and Audio & Airplay.
I have added code snippets from my AppDelegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// More code here ---------------------------------------------------
if (launchOptions) {
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo) { //apsInfo is not nil
[self performSelector:#selector(playCarAlarmAudio)
withObject:nil
afterDelay:1];
}
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
|UIUserNotificationTypeSound
|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
// More code here ---------------------------------------------------
}
The delegate methods to handle push notifications:
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Failed to register for push");
}
-(void) application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self respondToEventNotification:userInfo];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// [self respondToEventNotification:userInfo];
[self playAlarmAudio];
}
-(void) respondToEventNotification : (NSDictionary *) userInfo {
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
[localNotification setSoundName:#"alarm.mp3"];
[localNotification setFireDate:[NSDate date]];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
[self playAlarmAudio];
}
}
And to play the Alarm:
-(void) playAlarmAudio {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"alarm" ofType:#"mp3"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:nil];
self.audioPlayer.numberOfLoops = 1;
[self.audioPlayer play];
}
According to the following Apple documentation, the notification sound to be played is specified inside the notification payload dictionary (https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html):
The Notification Payload
Each remote notification includes a payload. The payload contains information about how the system should alert the user as well as any custom data you provide. In iOS 8 and later, the maximum size allowed for a notification payload is 2 kilobytes; Apple Push Notification service refuses any notification that exceeds this limit. (Prior to iOS 8 and in OS X, the maximum payload size is 256 bytes.)
For each notification, compose a JSON dictionary object (as defined by RFC 4627). This dictionary must contain another dictionary identified by the key aps. The aps dictionary can contain one or more properties that specify the following user notification types:
An alert message to display to the user
A number to badge the app icon with
A sound to play

Error Message Using Facebook Deprecated Headers

I have an application in Xcode 4.5 which integrates Facebook. I am using ARC. The application uses
native dialogs and therefore deprecated headers (ie Facebook.h). Apparently doing so leads to the following
error when closing/cleaning the active session:
"An instance 0xa089350 of class
FBSessionManualTokenCachingStrategy was deallocated while key value observers were still registered
with it. Observation info was leaked, and may even become mistakenly attached to some other object."
Upon researching this error, I assume that the issue is that when I init an instance of self.Facebook in the app delegate, Facebook
adds two observers rather than one, and then only one is cleaned up during logout. I have made numerous attempts to remove both instances, including every solution on this
page regarding this very error: facebook ios sdk log : strange message
None of these solutions have worked for me, including one solution I saw which involved deallocation which I cannot use as I am using ARC. Here is my code for opening and closing a session for reference:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
// Initiate a Facebook instance
self.facebook = [[Facebook alloc]
initWithAppId:FBSession.activeSession.appID
andDelegate:nil];
// Store the Facebook session information
self.facebook.accessToken = FBSession.activeSession.accessToken;
self.facebook.expirationDate = FBSession.activeSession.expirationDate;
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
// Clear out the Facebook instance
self.facebook = nil;
break;
default:
break;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
/*
* Opens a Facebook session and optionally shows the login UX.
*/
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI //do I need this method?
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"user_about_me",
#"read_friendlists",
#"read_stream",
#"friends_likes",
#"user_likes",
#"friends_photos",
#"user_photos",
nil];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session state:state
error:error]; }];
}
/*
* If we have a valid session at the time of openURL call, we handle
* Facebook transitions by passing the url argument to handleOpenURL
*/
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBSession.activeSession handleOpenURL:url];
}
- (void) closeSession {
[FBSession.activeSession closeAndClearTokenInformation];
}
If anyone can offer any guidance as to how to solve this I would greatly appreciate it.

Local Notification is displayed without didFinishLaunchingWithOptions:

I have quite an understanding issue with displaying local notifications.
As far as I was reading in other threads, one has first create and schedule the local notification with the application.
For displaying that notification, one has to use the delegates didFinishLaunchingWithOptions: (if app is in background operation) and didReceiveLocalNotification: (if app is in foreground).
Now even though I did NOT change the didFinishLaunchingWithOptions: method, the notification is already getting viewed when my app is in the background.
It wouldn't be that big of a problem if the didFinishLaunchingWithOptions: would at least be used when I specify it at all. But it doesn't.
So my problem is, that even though I haven't used the didFinishLaunchingWithOptions: method, the notification is getting displayed. When the user clicks on the notification, the app gets to foreground and the didReceiveLocalNotification: method is triggered and the notification is displayed again.
What I originally wanted to do is to cancelAllLocalNotifications on execution of didFinishLaunchingWithOptions:, but since it is not getting executed, I'm kinda stuck here.
Ok, there might be a workaround with applicationWillEnterForeground: but honestly, I'd like to understand, why the notification is getting displayed even without having specified that in didFinishLaunchingWithOptions:.
All of your help is really appreaciated!! Thanks!!
//
// myNotificationsClass.m
//
#import "myNotificationsClass.h"
#implementation myNotificationsClass
//Sets up a Local Notification with Message, TimeFromNow, BadgeNumber and UserInfo
//no Class Instance for calling this method needed!!
+ (void)setupLocalNotificationsWithMessage: (NSString *) message andTimeFromNow: (NSTimeInterval) seconds andAlertAction: (NSString *) alertAction andBadgeNumber: (NSInteger) badgeNumber andUserInfo: (NSDictionary *) infoDict {
//[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
// create date/time information
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
//setup Appearence and Message
localNotification.alertBody = message; //#"Time to get up!";
localNotification.alertAction = alertAction;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = badgeNumber;
localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
#end
//overwrites the viewWillAppear: Method from the primary Class to display a Test Notification
#implementation UIViewController (localNotification)
- (void)viewWillAppear:(BOOL)animated {
[myNotificationsClass setupLocalNotificationsWithMessage:#"First Test after 2 Seconds" andTimeFromNow:2 andAlertAction:#"GoTo iSnah" andBadgeNumber:7 andUserInfo:nil];
}
#end
//receive Local Notifications even if the App is in Foreground
//overwrites the primery method
#implementation UIResponder (localNotificationForeground)
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleName"]
message:notification.alertBody
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
//reset Badge
application.applicationIconBadgeNumber = 0;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Because I don't want the Notification to be displayed twice
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleName"]
message:notification.alertBody
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
//reset Badge
application.applicationIconBadgeNumber = 0;
}
return YES;
}
#end
You are very close. If the app is running in the background, the user responding to the notification will not cause the app to "launch". "Launch" means the app is not running at all (foreground or background). So only put code in there that you want to execute when the app launches or starts as a result of the user responding to your local notification.
So what you need for your didReceiveLocalNotification method is something to check the application state to see if it was in the foreground or in the background when the user responded to the local notification.
You might do something like the following to differentiate your logic between foreground and background:
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
if ( application.applicationState == UIApplicationStateActive ){
NSLog(#"Was already in the foreground");
}
else{
NSLog(#"Was in the background");
}
}
Minor point, however. Documentation states that the didReceiveLocalNotification method is invoked after application:didFinishLaunchingWithOptions: (if that method is implemented). So if you have both methods implemented you'll need to make sure the combination of the 2 work correctly in a "launch" situation.

Resources