等待 openParentApplication 回调完成

Wait for openParentApplication callback to complete

我的手表应用程序使用 openParentApplication 从其 WatchKit 扩展请求数据。它从手表应用程序的主页 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.")
    }

}

该扩展程序会填充适当的字典并在 returning 之前调用 reply()。准备和 return 数据需要一秒钟左右的时间。

问题来了: 有时有效,有时无效。有时主页会完美地接收数据。有时不会调用回调 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 至少是答案的一部分,但我不知道如何正确地将它们组合在一起。

非常感谢您的帮助。

GotData 方法处理完回复后,您需要更新 table。 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.")
    }
}

希望这能让您朝着正确的方向前进。