等待openParentApplication回调完成

时间:2015-03-08 05:22:38

标签: swift concurrency watchkit

我的观看应用使用openParentApplication从其WatchKit扩展程序请求数据。它从watch app的主页init()开始:

class HomePage : WKInterfaceController {
    @IBOutlet weak var table: WKInterfaceTable!

    override init() {
        super.init()
        NSLog("Starting home page.")

        Fetcher.GetData()         // Get data from WatchKit extension

        NSLog("Got data!")
        // Create table rows using GetData() return values
        self.table.setRowTypes(rowTypes)
        // etc...
    }

}

class Fetcher : NSObject {
    // Request data from WatchKit extension:
    class func GetData() {
        NSLog("GetData() begins.")
        WKInterfaceController.openParentApplication(
            ["command" : "sendData"],
            reply: {
                (returnedValues, error) -> Void in
                    GotData(returnedValues, error)
            }
        )
        NSLog("GetData() ends.")
    }

    // Callback for openParentApplication in GetData():
    class func GotData(dict: [String:AnyObject]?, error: NSError?) {
        NSLog("GotData() starts.")
        if error != nil {
            NSLog("Error in GotData(): %@", error!.debugDescription)
        }
        NSLog("GotData() processing...")

        // use the data returned in dict...

        NSLog("GotData() done.")
    }

}

扩展名填充适当的字典并在返回之前调用reply()。准备和返回数据需要一秒左右的时间。

问题在于: 有时它有效,有时它不起作用。有时主页会完美地接收数据。有时回调,GotData(),不会被调用。当它正常工作时:

21:00:46.151 WatchKit Extension: Starting home page.
21:00:46.171 WatchKit Extension: GetData() begins.
21:00:46.180 WatchKit Extension: GotData() starts.
21:00:47.175 WatchKit Extension: GotData() done.
21:00:47.177 WatchKit Extension: GetData() ends.
21:00:47.188 WatchKit Extension: Got data!

当它没有:

21:00:46.151 WatchKit Extension: Starting home page.
21:00:46.171 WatchKit Extension: GetData() begins.
21:00:46.177 WatchKit Extension: GetData() ends.
21:00:46.188 WatchKit Extension: Got data!

我发现:如果主页在willActivate()中执行操作,则GotData()回调永远不会运行。然而,这不是唯一的失败案例。

如何确保回调实际执行?我怀疑dispatch_groups至少是答案的一部分,但我不太了解它们是否正确。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

一旦GotData方法完成处理回复,您需要更新表。 Fetcher.GetData()调用是异步的,不会阻塞。因此,init函数的其余部分中的代码需要在回调(或闭包)内移动。这是一个修改后的逻辑版本,可以正确处理异步行为。

class HomePage : WKInterfaceController {
    @IBOutlet weak var table: WKInterfaceTable!

    override init() {
        super.init()
        NSLog("Starting home page.")

        Fetcher.GetData { dataValues in
            NSLog("Got data!")
            // Create table rows using GetData() return values
            self.table.setRowTypes(rowTypes)
            // etc...
        }
    }
}

class Fetcher : NSObject {
    // Request data from WatchKit extension:
    class func GetData(completionHandler: ([String: String]) -> Void) {
        NSLog("GetData() begins.")
        WKInterfaceController.openParentApplication(
            ["command" : "sendData"],
            reply: {
                (returnedValues, error) -> Void in
                GotData(returnedValues, error)
            }
        )
        NSLog("GetData() ends.")
    }

    // Callback for openParentApplication in GetData():
    class func GotData(dict: [String:AnyObject]?, error: NSError?, completionHandler: ([String: String]) -> Void) {
        NSLog("GotData() starts.")
        if error != nil {
            NSLog("Error in GotData(): %@", error!.debugDescription)
        }
        NSLog("GotData() processing...")

        // use the data returned in dict...

        let data = ["someKey": "someValue"]

        completionHandler(data)

        NSLog("GotData() done.")
    }
}

希望这会让你朝着正确的方向前进。