ios - 没有相应委托(delegate)方法的 UIApplicationBackgroundRefreshStatusDidChangeNotification 用法

标签 ios background-process nsnotificationcenter multitasking uiapplicationdelegate

我觉得iOS 7中引入的UIApplicationBackgroundRefreshStatusDidChangeNotification在不支持UIApplication委托(delegate)方法的情况下用处不大。因为,当用户打开我的应用程序的后台刷新状态时,应用程序不会收到通知。

这是我的通知处理程序...

- (void)applicationDidChangeBackgroundRefreshStatus:(NSNotification *)notification
{
    NSLog(@"applicationDidChangeBackgroundRefreshStatus with notification info = %@ and refresh status = %d", notification, UIApplication.sharedApplication.backgroundRefreshStatus);

    if (UIApplication.sharedApplication.backgroundRefreshStatus == UIBackgroundRefreshStatusAvailable) {
//        if ([CLLocationManager locationServicesEnabled]) {
            [self.locationManager startUpdatingLocation];
//        }
    }
}

如上所述,当 UIBackgroundRegreshStatus 通过应用 设置 > 常规 > 后台应用刷新 变为可用时,我想开始更新核心位置。我觉得 UIApplicationDelegate 中应该有一个适当的委托(delegate)方法来让应用程序知道此更改,以便应用程序可以重新建立它需要的一切。

要么我遗漏了一些东西(预先存在的 API),要么 Apple SDK 工程师对此通知的使用有一些其他/有限的意图。请指教。

最佳答案

理想情况下,您永远不必检查该设置。看起来您正在以错误的方式绕过后台获取。随着应用程序最小化,系统将定期唤醒您的应用程序并允许其执行任务。从您的代码中,您想更新位置。首先从这里开始,使用这个委托(delegate)方法,当应用程序被唤醒以进行后台获取时调用该方法

///具有“获取”后台模式的应用程序可能有机会在后台或在系统方便时获取更新的内容。在这些情况下将调用此方法。您应该在完成该操作后立即调用 fetchCompletionHandler,以便系统可以准确估计其功率和数据成本。 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler NS_AVAILABLE_IOS(7_0);

这就是你如何使用它,在你的应用程序委托(delegate)实现中,定义方法体如下

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{

    NSLog(@"APP IS AWAKE FOR A BACKGROUND FETCH");
    //do all the work you want to do 

//once done, its important to call the completion hadler, otherwise the system will complain
          completionHandler(UIBackgroundFetchResultNewData);

 }

但是,由于您正在更新位置,它有自己的代表,所以您只希望在代表返回时调用完成处理程序,而不是在此之前。调用完成处理程序将使您的应用程序返回 sleep 状态。由于完成处理程序是一个 block 对象,它可以像任何其他对象一样传递。一种方法如下:在应用程序委托(delegate)头文件中,定义一个 block 对象:

void (^fetchCompletionHandler)(UIBackgroundFetchResult);

然后在你的 performFetchWithCompletionHandler 中有:

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    fetchCompletionHandler = completionHandler;

    NSLog(@"APP IS AWAKE FOR A BACKGROUND FETCH");
    //do all the work you want to do 
            [self.locationManager startUpdatingLocation];


 }

在某个适当的时候,在您的位置委托(delegate)方法返回后,您调用

fetchCompletionHandler (UIBackgroundFetchResultNewData);

请务必检查您的 fetchCompletionHandler 是否为非 nill,当 nil 时调用它会立即使您的应用程序崩溃。在此处阅读有关 Apple 文档 block 的更多信息 https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html

还可以查看调用 [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval: ];指定后台提取操作之间必须经过的最短时间。

您可能会将其放入您的应用委托(delegate)应用程序 didFinishLaunchingWithOptions 方法中。

希望这对你有帮助。

关于ios - 没有相应委托(delegate)方法的 UIApplicationBackgroundRefreshStatusDidChangeNotification 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19235183/

相关文章:

objective-c - SearchBar 与隐藏的 UITableView iOS

bash - 即使第一个命令的子进程仍在后台运行,也关闭管道

ios - 多个长时间运行的后台任务

android - 在 Android 中为 "networking"使用另一个线程

iphone - "unrecognized selector sent to instance"当键盘出现时

ios - 分数增加无限

ios - GDataServiceGoogleDocs

ios - 我如何从 __TEXT 中分离出来并进入 mach-o 二进制文件的新段?

ios - NSNotificationCenter postNotificationName 在 swift 和 object-c 中崩溃,为什么?