本地通知在模拟器上可以正常工作,但在设备上无法正常工作

4

我阅读了一些关于如何使用UILocalNotification的指南。所以我尝试了一下,但从第一次尝试起就没有成功。我在AppDelegate.m中使用以下代码注册通知:

    - (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;
    }

并且在应用正在运行时接收通知:

    - (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");
         }


    }

在模拟器和设备上一切都正常 - 当应用程序运行时,我会收到我的预定通知。但是我需要在应用程序处于非活动状态(按下主页键一次)时接收通知。
问题在于,如果我例如在按钮按下时设置我的通知,我将毫无问题地收到它,并且它将显示在通知中心中,并且将添加徽章到我的应用程序图标上,就像我想要的那样。但是我只想在我的 AFNetworking 任务结束时接收通知。
为了设置通知,我使用以下方法:
    -(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);
        }];
    }

主要问题是这种方法仅适用于iOS版本8.0的模拟器,不适用于iOS 7.1.1上的iPhone 4和iOS 8.1.2上的iPhone 5c,也不适用于iOS 7.1的模拟器。 在真实设备和iOS 7.1+的模拟器上,我从未收到过后台通知,只有当我打开应用程序时才能收到通知(然后它会像我在AppDelegate.m中设置的那样显示提示)。 我很高兴听取任何建议和帮助。


为什么你要将火灾日期设置为立即?这样不会一直在前台触发吗?它应该在未来的某个日期触发。 - Steven Ritchie
@StevenRitchie 因为它符合我的条件。当 progCreate == 100 时,我需要接收通知。 - vendettacore
@Bhavin 不是,它是通过服务器端的推送通知解决的,本地通知仍然无法显示。 - vendettacore
遇到了相同的问题...我不知道为什么。 - Bhavin Bhadani
如果您需要在后台立即执行此操作,您需要将其添加到主运行循环中。对于任何遇到上述问题的人。 - Abu Ul Hassan
3个回答

5

我看到您正在使用Objective-C。考虑到这个问题是一年前提出的,您可能已经解决了这个问题或者现在正在使用Swift 2.0。我也遇到了同样的问题,但是我能够通过添加以下代码来解决Swift 2.0中的问题。

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.


3

在iOS 8.0+模拟器中收到通知的事实是iOS模拟器运行时的一种限制。在设备上,当您的应用程序处于后台时,它实际上并未运行,任务被暂停。而在iOS模拟器中,任务会继续在后台运行。


你在说哪个任务?如果你是指我的 getProgress 任务在后台不起作用,那是错误的。因为当应用程序没有运行并重新打开时,进度会改变(正如它应该做的),所以我不明白为什么如果我的任务工作,通知为什么不会在后台发送。 - vendettacore
当运行时,您的应用程序是一项mach任务/BSD进程。当用户将您的应用程序置于后台时,该任务被挂起(您在CPU上没有时间)。在模拟器中,当您的任务被置于后台时仍会继续运行。这是模拟器运行时的错误,与设备不匹配。 - Jeremy Huddleston Sequoia
是的,我尝试使用UILocalNotification发布一条样本通知。在iOS模拟器“iPhone 6/8.3”上无法正常工作。 - Shanmugaraja G

0
有时候我们不能立即收到本地通知,但大约一个小时后我会收到通知。因此,请等待一段时间然后再次检查。

但是在我的情况下,我需要即时通知,因为它们会通知我已完成下载等事项。 - vendettacore
请检查您为该通知设置的时间和日期。 - Nupur Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接