didFinishUserInfoTransfer成功完成 - 但仍然使用outstandingUserInfoTransfers对象

时间:2016-01-13 17:16:25

标签: watchkit watchconnectivity wcsession

首先我使用" transferUserInfo" -method将字典从iPhone发送到Apple Watch:

let dicty = //...my dictionary of property-list values...
if WCSession.isSupported() {
    let session = WCSession.defaultSession()
    if session.paired == true {  // Check if your Watch is paired with your iPhone
        if session.watchAppInstalled == true {  // Check if your Watch-App is installed on your Watch
            session.transferUserInfo(dicty)
        }
    }
}

然后我使用以下委托回调方法" didFinishUserInfoTransfer"检查转移的状态:

func session(session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?) {
    if error == nil {
        let session = WCSession.defaultSession()
        let transfers = session.outstandingUserInfoTransfers
        if transfers.count > 0 {  //--> is always > 0, why ?????????
            for trans in transfers {
                trans.cancel()  // cancel transfer that will be sent by updateApplicationContext
                let dict = trans.userInfo
                session.transferUserInfo(dict)  //--> creates enless-transfer cycle !!!!!
            }
        }
    }
    else {
        print(error)
    }
}

在Apple文档中,它讲述了didFinishUserInfoTransfer方法:

The session object calls this method when a data transfer initiated by the
current app finished, either successfully or unsuccessfully. Use this method
to note that the transfer completed or to respond to errors, perhaps by
trying to send the data again at a later time.

到目前为止很好 - 我明白了。但是现在 - 有些事我不明白:

如果输入didFinishUserInfoTransfer并且错误== nil,为什么地球上的session.outstandingUserInfoTransfers COUNT大于零??????

根据Apple文档,didFinishUserInfoTransfer唯一的非错误状态应该是转移结束时!它似乎没有结束......为什么???

感谢您对此作出任何澄清。

而且,我很高兴有关如何正确使用这3种方法的任何示例代码! (即

  • session.transferUserInfo(dicty)

  • didFinishUserInfoTransfer

  • session.outstandingUserInfoTransfers)

2 个答案:

答案 0 :(得分:1)

在委托回调返回之前,似乎不会从didFinishUserInfoTransfer中删除触发outstandingUserInfoTransfers回调的userInfoTransfer。要获得所需的行为(其中count可以降为0),您需要从委托回调线程调度dispatch_async。所以这应该有效:

func session(session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?) {
    if error == nil {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            let transfers = session.outstandingUserInfoTransfers
            if transfers.count > 0 {  //--> will in most cases now be 0
                for trans in transfers {
                    trans.cancel()  // cancel transfer that will be sent by updateApplicationContext
                    let dict = trans.userInfo
                    session.transferUserInfo(dict)  // ***
                }
            }
        });
    }
    else {
        print(error)
    }
}

那就是说,我不太明白为什么你想要取消所有剩余的未完成的userInfoTransfer任何一个完成,只是为了重新排队(有问题的地方由***表示)< / p>

答案 1 :(得分:1)

就我阅读文档而言,存在一些误解:仅在发生错误时再次发送。如果没有引发错误,则具有未完成的userInfoTransfers是预期的行为;他们尚未成功发送并仍在排队。

顺便说一下。代码使用实际的dispatchQueue。

func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) {

if error != nil {  // resend if an error occured

        DispatchQueue.main.async {

            let transfers = session.outstandingUserInfoTransfers
            if transfers.count > 0 {

                // print("open transfers: \(transfers.count)")

                for trans in transfers {

                    // print("resend transfer")

                    trans.cancel()  // cancel transfer
                    let dict = trans.userInfo
                    session.transferUserInfo(dict)  // send again
                }
            }
        }
    }
}