与 WatchKit 应用的行为不一致 - Swift

Inconsistent behaviour with WatchKit app - Swift

我正在尝试让 iOS 应用程序与手表进行通信,但我总是遇到不一致的行为 - 通信速度太慢,或者 none 的数据在全部.

此外,watchKit 运行时我没有看到任何 "Phone disabled" 屏幕(这会导致崩溃,因为我需要先从 phone 获取数据)。

这就是我在 iPhone 应用程序中建立 WCSession 的内容

应用代理

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

       if NSClassFromString("WCSession") != nil {
            if #available(iOS 9.0, *) {
                if(WCSession.isSupported()){
                    self.session = WCSession.defaultSession()
                    self.session.delegate = self
                    self.session.activateSession()
                    if session.paired {
                        print("Watch connected")
                    } else {
                        print("No watch")
                    }
                }
            } else {
            }}

        if NSClassFromString("WCSession") != nil {
            if(WCSession.isSupported()){
                session.sendMessage(["b":"delegateSaysHi"], replyHandler: nil, errorHandler: nil)
            }}
}

MainViewController (viewDidLoad)

if NSClassFromString("WCSession") != nil {
        if(WCSession.isSupported()){
            self.session = WCSession.defaultSession()
            self.session.delegate = self
            self.session.activateSession()
            if session.paired {
                print("Watch connected")
            } else {
                print("No watch")
            }
    }}

MainViewController(将大量数据从 iOS 应用程序传输到 watchKit 应用程序的方法)

    func transferData(){
    do {
        let dataArray = ["somedata": array2d1]
        try WCSession.defaultSession().updateApplicationContext(dataArray)
        let dataArray1 = ["somedata1": array2d2]
        try WCSession.defaultSession().updateApplicationContext(dataArray1)
        let dataArray2 = ["somedata2": array2d3]
        try WCSession.defaultSession().updateApplicationContext(dataArray2)
            let dataArray3 = ["somedata3": array2d4]
        try WCSession.defaultSession().updateApplicationContext(dataArray3)

// and up to 12
        }

    catch {
        print("Something wrong happened")
    }
    }

这是 watchKit 应用

应用代理

func applicationDidFinishLaunching() {
    if(WCSession.isSupported()){
        self.session = WCSession.defaultSession()
        self.session.delegate = self
        self.session.activateSession()
    }
}

func applicationDidBecomeActive() {
    if(WCSession.isSupported()){
        self.session.sendMessage(["b":"peek"], replyHandler: nil, errorHandler: nil)
    }

InterfaceController (awakeWithContext)

if(WCSession.defaultSession().reachable){
    self.session.sendMessage(["b":"peek"], replyHandler: nil, errorHandler: nil)
}

ApplicationContext数据接收方法

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {

    dispatch_async(dispatch_get_main_queue()) { () -> Void in

        if let retrievedArray1 = applicationContext["somedata"] as? [[String]] {
                self.watchAppArray = retrievedArray1

        }
        if let retrievedArray2 = applicationContext["somedata2"] as? [[String]] {

             self.watchAppArray = retrievedArray1

// and so on for 12 arrays sent from phone

        }

        }
    }}

非常欢迎任何关于清理情况的建议!

谢谢。

多个delegates/activations:

您在应用的不同部分重复设置、委派和激活会话。您不断更改您的委托,因此在您将处理委托给应用程序的不同部分后,应用程序的一个部分中的代码将不再被使用。

您应该在整个应用中使用一个 session/delegate。一种解决方案是设置一个 WCSession 单例,它在应用程序范围内可用。 a guide 将引导您完成该过程。

只会发送最新的应用程序上下文:

通过尝试对多个应用程序上下文请求进行排队,当系统开始传输它时,较早的请求将不再在队列中,因为系统已经用较晚的上下文替换了前面的上下文。所以只有最后一个 (dataArray3) 会被传输。

Use the updateApplicationContext:error: method to communicate recent state information to the counterpart. When the counterpart wakes, it can use this information to update its own state. ... This method overwrites the previous data dictionary, so use this method when your app needs only the most recent data values.

如果所有数组都代表您的应用程序的最新状态,您希望将它们一起传输到一个字典中。

var dataArray = [String: AnyObject]()
dataArray["somedata"] = array2d1
dataArray["somedata1"] = array2d2
dataArray["somedata2"] = array2d3
dataArray["somedata3"] = array2d4

do {
    try session.updateApplicationContext(dataArray)
}
catch {
    print(error)
}

在您的 sendMessage 代码中添加一些错误处理可能也会有所帮助,因为配对的设备可能并不总是可用。

通讯速度慢:

关于通讯速度太慢,有两个问题。

  • 转移可能不会立即发生。

    When only one session is active, the active session may still send updates and transfer files, but those transfers happen opportunistically in the background.

    Remember that background transfers are not be delivered immediately. The system sends data as quickly as possible but transfers are not instantaneous, and the system may delay transfers slightly to improve power usage. Also, sending a large data file requires a commensurate amount of time to transmit the data to the other device and process it on the receiving side.

  • 您发送的数据越多,transmit/receive 所需的时间就越长。

    When sending messages, send only the data that your app needs. All transfers involve sending data wireless to the counterpart app, which consumes power. Rather than sending all of your data every time, send only the items that have changed.

您可以控制发送的数据量,以及数据是交互发送还是在后台发送。如果可以联系到手表,您可以使用 sendMessage 进行即时通信。如果无法访问,您可以使用后台方法。