openParentApplication 仅当应用程序在前台 运行 时才有效

openParentApplication only works when the app is running in the foreground

我正在尝试使用 openParentApplication 从服务器请求数据并在手表扩展中使用它,但是当主应用程序不在 运行 中时我没有得到任何回复前景。当主应用程序在前台 运行 时,一切正常。

我以前遇到过这个问题,原因是您没有注册长时间的 运行 后台操作,系统将其杀死。 这就是我的排序方式,请参阅注释以获取解释,这些都在 AppDelegate 文件中,并且在 swift 中,但您可以轻松地将其移植到 Objective-c:

private var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid

func registerBackgroundTask() {
        backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler {
            [unowned self] in
            self.endBackgroundTask()
        }
        assert(backgroundTask != UIBackgroundTaskInvalid)
    }

func endBackgroundTask() {
    UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

// MARK: - Watch Kit
func application(application: UIApplication, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?, reply: (([NSObject : AnyObject]!) -> Void)!) {

    registerBackgroundTask()

    // Fetch the data from the network here
    // In the competition handler you need to call:
    // the nil can be replaced with something else you want to pass back to the watch kit
    reply(nil)
    if self.backgroundTask != UIBackgroundTaskInvalid {
        self.endBackgroundTask()
    }
}

只是添加一些 Obj-c 等效项来执行此操作,尽管我使用的是直接 GCD,所以它是一种略有不同的方法。

 __block UIBackgroundTaskIdentifier identifier = UIBackgroundTaskInvalid;
dispatch_block_t endBlock = ^ {
    if (identifier != UIBackgroundTaskInvalid) {
        [application endBackgroundTask:identifier];
    }
    identifier = UIBackgroundTaskInvalid;
};
identifier = [application beginBackgroundTaskWithExpirationHandler:endBlock];

reply = ^(NSDictionary *replyInfo) {
    reply(replyInfo);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        endBlock();
    });
};