【问题标题】:When we swipe to quit an application if applicationDidEnterBackground is not called 100% of the time how do we reliably save data?如果在 100% 的情况下都没有调用 applicationDidEnterBackground,我们滑动退出应用程序时,我们如何可靠地保存数据?
【发布时间】:2015-09-12 03:47:13
【问题描述】:

我之前问过这个问题。我想我的问题用错了。基本上我想在应用程序终止时将数据从我的应用程序保存到解析后端。即应用程序从应用程序列表中被刷掉并杀死。 iOS 文档说实际上会调用 applicationDidEnterBackground 而不是 applicationWillTerminate,因此可以在此方法中完成任何工作。

applicationWillTerminate: 对于不支持后台执行或与 iOS 3.x 或更早版本链接的应用程序,当用户退出应用程序时始终调用此方法。对于支持后台执行的应用程序,当用户退出应用程序时通常不会调用此方法,因为在这种情况下应用程序只是移动到后台。但是,该方法可能会在应用程序在后台运行(未挂起)并且系统出于某种原因需要终止它的情况下调用。

但是,这不是 100%,并且从我的测试 applicationDidEnterBackground 不会在我每次退出应用程序时调用。那么当一个应用程序以 100% 的保证被终止时,如何保存数据呢?

这是我在 applicationDidEnterBackground 时保存的代码:

- (void)applicationDidEnterBackground:(UIApplication *)application
 {
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        //End the Task
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if([self getController]){                
            CatsViewController *catsViewController = [self getController];
            if(catsViewController.currentUser){                    
                int count = (int)[MyViewController.currentUser.messages count];
                PFInstallation *currentInstallation = [PFInstallation currentInstallation];
                currentInstallation.badge = count;
                [currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                    [application endBackgroundTask:bgTask];
                    bgTask = UIBackgroundTaskInvalid;
                }];                    
            }                
            else{                    
                [application endBackgroundTask:bgTask];
                bgTask = UIBackgroundTaskInvalid;
            }
        }            
        else{                
            [application endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }
    });
}

如果能得到这方面的任何指示,那就太好了。谢谢

【问题讨论】:

  • 任何你不能保存更改而不是“退出”的原因
  • 我正在尝试使解析与我的徽章编号保持同步(徽章编号是我的应用程序中的消息数)。与其每次删除消息以更新对象时都进行额外的解析,不如在应用程序进入后台或通过单个调用退出时执行此操作。即用户打开应用删除 3 条消息,然后切换应用单个 api 调用以更新徽章计数而不是 3。

标签: ios objective-c


【解决方案1】:

您可以使用 applicationWillResignActive 来处理类似的事情。当用户打开他的通知中心时,它也会被调用。当用户进入应用切换器时也会调用它。如果他随后杀死了该应用程序,那么您将无能为力,因为从切换器中滑动该应用程序将发送 SIGKILL。如果幸运的话,您可以利用 willResignActive 在此之前完成后台任务。

我总是分别使用 applicationWillResignActive 和 applicationDidBecomeActive,因为它们都涵盖了应用程序不在前台的更广泛的情况。

另请阅读this answer here(及以上)

【讨论】:

  • 嘿,谢谢你,所以如果我将我的代码移动到 applicationWillResignActive 它应该做同样的事情,但也可以在应用程序切换器中覆盖我,对吧?正在测试一点,因为我正在做一个 API 调用,你必须是超级人类才能比调用所需的时间更快地滑动,所以看起来不错......
【解决方案2】:

这是解决方案。如果您滑动退出您的应用程序,它会 不调用 applicationDidEnterBackground 因为应用程序终止。 应用程序终止时调用的 AppDelegate 方法是 这个方法:

1.) You need to add the appWillTerminate observer in you app delegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//This is the observer you need to add so that the applicationWillTerminate app delegate method will get called.
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];

}

2.)Add the codes for saving before your app is terminated.
-(void)applicationWillTerminate:(UIApplication *)application{
//Add your codes like saving data here
}

【讨论】:

  • applicationWillTerminate 并不总是被调用,所以这不是一个解决方案。问题明确指出这种方法不起作用,那么发布它的原因是什么?此外,没有理由让您的应用程序监听 UIApplicationWillTerminateNotification,因为该通知是由 applicationWillTerminate 发布的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多