First I use the "transferUserInfo"-method in order to send a dictionary from the iPhone to the 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)
}
}
}
Then I am using the following delegate callback method "didFinishUserInfoTransfer" to check upon the state of the transfer:
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)
}
}
In the Apple documentation, it sais about the didFinishUserInfoTransfer method:
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.
So far so good - I understood. But now - there is something I do not understand:
If didFinishUserInfoTransfer is entered and the error == nil, why on earth can the session.outstandingUserInfoTransfers COUNT be bigger than zero ??????
According to the Apple-documentation, the only non-error-state of didFinishUserInfoTransfer should be when the transfer is over !! Bit it does not seem to be over... Why ???
Thanks for any clarification on this.
And also, I am glad of any example-code on how to use these 3 methods correctly ! (i.e.
session.transferUserInfo(dicty)
didFinishUserInfoTransfer
session.outstandingUserInfoTransfers)
It seems that the userInfoTransfer that triggers the didFinishUserInfoTransfer
callback is not removed from the outstandingUserInfoTransfers
until the delegate callback has returned. To get the behavior you want (where count can go down to 0) you'd want to dispatch_async away from the delegate callback thread. So this should work:
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)
}
}
That said, I don't quite understand why you'd want to cancel all the remaining outstanding userInfoTransfers whenever any of them completes, just to re-queue them (spot in question is indicated by ***
)