15

我正在开发一个应用程序,如果终止,它将无法工作。它有一些后台任务。如果应用程序终止,我想显示本地通知。有些应用程序可以做到这一点,这意味着这是可行的。但我无法找到方法。

我试图在 applicationWillTerminate: 方法的 appdelegate 中设置本地通知,并在我的视图控制器中添加了应用程序终止的通知,但是当应用程序实际终止时没有调用任何方法。

- (void)applicationWillTerminate:(UIApplication *)application
{
    NSLog(@"terminated");
    UIApplication * app = [UIApplication sharedApplication];
    NSDate *date = [[NSDate date] dateByAddingTimeInterval:15];
    UILocalNotification *alarm = [[UILocalNotification alloc] init] ;
    if (alarm) {
        alarm.fireDate = [NSDate date];
        alarm.timeZone = [NSTimeZone defaultTimeZone];
        alarm.repeatInterval = 0;
        alarm.alertBody = @"This app does not work if terminated";
        alarm.alertAction = @"Open";
        [app scheduleLocalNotification:alarm];
    }

    [app presentLocalNotificationNow:alarm];
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

任何帮助都会很棒。

提前致谢 !!!

4

5 回答 5

14

应用程序可以在“未来”日期和时间创建本地通知,用于通知用户应用程序已终止。如果他们然后点击应用程序,他们可以重新启动您的应用程序。

这在我的应用程序中工作,该应用程序在 info.plist 中使用/需要蓝牙中心(因此它将在后台运行)。我假设您已经将应用程序配置为在 info.plist 中的后台运行。

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Schedule an alarm here to warn the user that they have terminated an application and if they want to re-activate it.

    NSDate * theDate = [[NSDate date] dateByAddingTimeInterval:10]; // set a localnotificaiton for 10 seconds

    UIApplication* app = [UIApplication sharedApplication];
    NSArray*    oldNotifications = [app scheduledLocalNotifications];


    // Clear out the old notification before scheduling a new one.
    if ([oldNotifications count] > 0)
        [app cancelAllLocalNotifications];

    // Create a new notification.
    UILocalNotification* alarm = [[UILocalNotification alloc] init];
    if (alarm)
    {
        alarm.fireDate = theDate;
        alarm.timeZone = [NSTimeZone defaultTimeZone];
        alarm.repeatInterval = 0;
        alarm.soundName = @"sonar";
        alarm.alertBody =@"Background uploads are disabled. Tap here to re-activate uploads." ;

        [app scheduleLocalNotification:alarm];
    }

}
于 2014-02-11T22:06:55.627 回答
6

当您的应用程序在后台暂停时,您将不会收到任何通知。

iOS 将为您的应用程序进度发送一个 kill -9 信号,而您的应用程序刚刚被终止,这与用户从快速启动托盘中终止您的应用程序时发生的事情相同。

苹果文档

即使您使用 iOS SDK 4 及更高版本开发您的应用程序,您仍然必须准备好您的应用程序在没有任何通知的情况下被终止。用户可以使用多任务 UI 明确地终止应用程序。此外,如果内存受到限制,系统可能会从内存中删除应用程序以腾出更多空间。暂停的应用程序不会收到终止通知,但如果您的应用程序当前在后台状态下运行(并且未暂停),系统会调用您的应用程序委托的 applicationWillTerminate: 方法。您的应用无法通过此方法请求额外的后台执行时间。

于 2013-08-01T08:02:35.967 回答
3

我和你有同样的问题。但是,我发现如果我没有设置 fireDate 它开始工作。

- (void)applicationWillTerminate:(UIApplication *)application
{
//Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
    if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1){
        //Annoy The User - Set a badge
        [application setApplicationIconBadgeNumber:1];

        //Try and alert the user
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = @"Tracking disabled. Tap to resume.";
        notification.soundName = UILocalNotificationDefaultSoundName;
        [application scheduleLocalNotification:notification];
    }
#endif
}

不过我必须警告你,它不适用于空的应用程序。它确实适用于我的应用程序,它在内存中有很多视图,因此它必须与释放内存所需的时间有关。

W

于 2013-11-12T10:38:20.533 回答
1

我可以使用以下代码在 appWillTerminate 中安排本地通知:

    let localNotification = UILocalNotification.init()
    localNotification.fireDate = Date.init(timeIntervalSince1970: Date().timeIntervalSince1970 + 1.5)
    localNotification.timeZone = TimeZone.current
    localNotification.repeatInterval = NSCalendar.Unit(rawValue: 0)
    localNotification.alertBody = "Did terminate app"
    localNotification.soundName = "sonar"
    UIApplication.shared.scheduleLocalNotification(localNotification)
    // block main thread
    DispatchQueue.global().async {
        sleep(1)
        DispatchQueue.main.sync {
            CFRunLoopStop(CFRunLoopGetCurrent())
        }
    }
    CFRunLoopRun()
于 2018-01-16T15:31:22.017 回答
0

从应用程序双击主页按钮并滑动以杀死应用程序始终调用applicationWillTerminate。如果您单击并在后台发送应用程序,然后再次双击以滑动并杀死应用程序,则可能不会每次都调用applicationWillTerminate 。

- (void)applicationWillTerminate:(UIApplication *)application
{
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.userInfo =  [NSDictionary dictionaryWithObject:@"killed.app" forKey:@"Killed"];
        notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2]; // Give some time for firing the notification at least 2 seconds.
        notification.alertBody = @"App is killed.";
        notification.soundName = UILocalNotificationDefaultSoundName;
        notification.timeZone = [NSTimeZone systemTimeZone];
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        sleep(1); // I noticed that adding sleep is required as it makes sure the notification is set before the app exits.
}
于 2017-12-06T07:08:11.067 回答