【问题标题】:openParentApplication only works when the app is running in the foregroundopenParentApplication 仅在应用程序在前台运行时有效
【发布时间】:2015-06-08 07:40:34
【问题描述】:

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

【问题讨论】:

    标签: ios objective-c iphone watchkit apple-watch


    【解决方案1】:

    我之前遇到过这个问题,原因是您没有注册长时间运行的后台操作并且系统将其杀死。 这就是我的排序方式,请参阅 cmets 以获得解释,这些都在 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()
        }
    }
    

    【讨论】:

    • 非常感谢您现在通信正常,但是当应用程序未在前台运行时,我收到此错误:iPhone App never called reply()
    • @mohammedalwaili 确保您从您的比赛处理程序以及如果您有其他处理程序失败的情况下调用回复(nil)。您必须从每个可能的场景中调用应用程序 handleWatchKitExtensionRequest 的回复(nil):成功/失败。
    • 我已经在模拟器上测试了应用程序,一切正常,但是在真正的 Apple Watch 上测试应用程序时,当我在 iPhone 上终止应用程序时,我没有得到数据。当应用程序在 iPhone 上没有被杀死时,我会恢复数据你知道为什么吗?
    • @mohammedalwaili 它对我有用。尝试进行一些调试以缩小可能出现问题的区域。我在真正的应用程序中使用了这段代码,一切都很好。
    • iOS 确实不会在调用 openParentApplication 后的正确时间在后台启动终止的应用程序。请参阅我关于该主题的问答。
    【解决方案2】:

    只需添加一些等效的 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();
        });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-02
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      相关资源
      最近更新 更多