4

I've read some guides of how to use UILocalNotification's. So I've tried and haven't succeed since my first try. To register notifications in AppDelegate.m I use:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    ...
    //if it is iOS 8
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
    {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else // if iOS 7
    {
        UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
        [application registerForRemoteNotificationTypes:myTypes];
    }

    UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (locationNotification) {
        // Set icon badge number to zero
        application.applicationIconBadgeNumber = 0;
        }

        return YES;
    }

and to recieve notification when app is running:

    - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
    {
    NSLog(@"notification recieved %@",notification.alertBody);
     //  NSLog(@"notification userinfo %@",notification.userInfo);
    UIApplicationState state = [application applicationState];
    if (state == UIApplicationStateActive) {
        NSLog(@"notification fired in foreground");
         UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Notification!"
                                                      message:notification.alertBody
                                                     delegate:nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];

    [message show];
    } else if (state == UIApplicationStateInactive){
        NSLog(@"notification fired in inactive");

    } else if (state == UIApplicationStateBackground){
        NSLog(@"notification fired in background");
         }


    }

And everything is ok on simulator and on device too - when app is running I get my sheduled notification. But I need recieve notifications when app is not running i.e. when app is inactive (home pressed one time)

The problem is that if I shedule my notification on button press for example, I'll get it without any problem and it'll be shown in notification center and badge will be added on my app's icon as I want. But I want recieve notification only when my AFNetworking task will be ended up.

For setting notification I use following method:

    -(void)getProgress{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSString *token = [defaults objectForKey:@"token"];
    NSString *header = [NSString stringWithFormat:@"Bearer %@",token];
    NSDictionary *params = @{@"lang": @"en",@"project":projId};
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    [manager.requestSerializer setValue:header forHTTPHeaderField:@"Authorization"];
    [manager POST:@"http://example.com/api/get-progress" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([[responseObject objectForKey:@"result"]isEqualToString:@"success"]){
            progCreate = [responseObject objectForKey:@"progress"];
            if ([progCreate intValue]==100){
                //shedule notification for immediately showing
              UILocalNotification* localNotification = [[UILocalNotification alloc] init];
              localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
              localNotification.alertBody = [NSString stringWithFormat:@"Notification text!"];
              localNotification.alertAction = @"Show";
              localNotification.timeZone = [NSTimeZone defaultTimeZone];
              localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
              [localNotification setSoundName:UILocalNotificationDefaultSoundName];
              [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
             //  [[UIApplication sharedApplication]presentLocalNotificationNow:localNotification]; the same result as above
            }

        }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        NSLog(@"Error: %@", error);
        }];
    }

The main problem is that this method works only on simulator with iOS version 8.0 and it doesn't work on iPhone 4 with iOS 7.1.1 and iPhone 5c with iOS 8.1.2 it also doesn't work on simulator with iOS 7.1. On real devices and simulator with iOS 7.1+ I've never been noticed about recieveing notification in background and only can get it if I'll open app (then it show me alert as I set in AppDelegate.m) I'll glad for any suggestions and any help.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
vendettacore
  • 1,439
  • 1
  • 13
  • 28

3 Answers3

5

I see that you're using Objective-C. Considering this question was asked a year ago, you've probably either figured this out or you're using Swift 2.0 now. I had the same issue and I was able to resolve it with Swift 2.0 by adding the following code.

AppDelegate.swift:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil))
    application.beginBackgroundTaskWithName("showNotification", expirationHandler: nil)

    return true
}

You can see my full answer here.

Community
  • 1
  • 1
Ivan
  • 665
  • 2
  • 10
  • 28
3

The fact that you get the notification in the iOS 8.0+ Simulator is a limitation of the iOS Simulator runtime. On device, when your app is in the background, it is not actually running, the task gets suspended. In the iOS Simulator, the task continues to run in the background.

Jeremy Huddleston Sequoia
  • 22,938
  • 5
  • 78
  • 86
  • what task are you talking about? If you mean that my `getProgress` task is not working in background it's wrong. Because when app is not running and then reopened progress change (as it must) so I can't understand why does notification not sent in background if my task works – vendettacore Jan 22 '15 at 09:19
  • When running, your app is a mach task/BSD process. The task is suspended (you get no time on the CPU) when the user places your app in the background. In the sim, your task continues to run when placed in the background. This is a bug in the simulator runtime where it does not match device. – Jeremy Huddleston Sequoia Jan 22 '15 at 09:23
  • Yes, I tried to post a sample notification using UILocalNotification. It is not working on iOS Simulator "iPhone 6 / 8.3" – Shanmugaraja G Jul 31 '15 at 12:32
0

Sometimes we don't get Local notification instantly but after 1hour almost I get notification. So, wait for a particular time then again check.