Я написал два приложения, первое с использованием transferUserInfo
, что вызвало слишком большую задержку (я полагаю, потому что это отправляет вещи в фоновом режиме). Я переключился на sendMessage
и был очень доволен результатами (более быстрое время отклика). При попытке запустить приложение на моем реальном iPhone и Apple Watch я получил Transfer timed out.
Вот полный код и пример одной из отладок:
iPhone:
// ViewController.swift
import UIKit
import Foundation
import WatchConnectivity
class WatchManager: UIViewController, WCSessionDelegate {
var counter = 0
var watchSession: WCSession? {
didSet {
if let session = watchSession {
session.delegate = self
session.activate()
}
}
}
override func viewDidLoad(){
super.viewDidLoad()
watchSession = WCSession.default
}
private func sendDict(_ dict: [String: Any]) {
self.watchSession?.sendMessage(dict, replyHandler: nil, errorHandler: {error in print(error.localizedDescription)})
}
@IBOutlet weak var transferButton: UIButton!
@IBOutlet weak var label: UILabel!
@IBAction func dataTransfer(_ sender: Any) {
sendDict(["DataKey": counter])
counter+=1
print("sent")
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("Session activation did complete")
}
public func sessionDidBecomeInactive(_ session: WCSession) {
print("session did become inactive")
}
public func sessionDidDeactivate(_ session: WCSession) {
print("session did deactivate")
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
print("phone received app context: ", message)
if let temperature = message["DataKey"] as? String {
DispatchQueue.main.async {
self.transferButton.setTitle(temperature, for: .normal)
self.label.text=temperature
}
}
}
}
Apple Watch:
// InterfaceController.swift
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController {
var watchSession: WCSession? {
didSet {
if let session = watchSession {
session.delegate = self
session.activate()
}
}
}
@IBOutlet weak var temperatureLabel: WKInterfaceButton!
private func sendDict(_ dict: [String: Any]) {
self.watchSession?.sendMessage(dict, replyHandler: nil, errorHandler: {error in print(error.localizedDescription)})
}
@IBAction func button() {
let urg = ["DataKey":UUID().uuidString]
sendDict(urg)
print("watch sent app context \(urg)")
}
}
extension InterfaceController: WCSessionDelegate {
#if os(iOS)
public func sessionDidBecomeInactive(_ session: WCSession) { }
public func sessionDidDeactivate(_ session: WCSession) {
session.activate()
}
#endif
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("Session activation did complete")
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
print("watch received app context: ", message)
if let temperature = message["DataKey"] as? Int {
self.temperatureLabel.setTitle(String(temperature))
}
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
watchSession = WCSession.default
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
Пример отладки:
Session activation did complete
watch sent app context ["DataKey": "AF793FC6-7A16-4D7D-9A3B-D3BB960EC9D9"]
2019-01-13 21:07:43.524717-0800 testApp WatchKit Extension[1240:1178401] [WC] -[WCSession onqueue_handleMessageCompletionWithError:withMessageID:] C385FF5F-5EA1-478B-A930-54066C2F0B0F due to WCErrorCodeTransferTimedOut -> IDSErrorTypeTimedOut -> IDSResponseTimedOut
2019-01-13 21:07:43.525001-0800 testApp WatchKit Extension[1240:1178401] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] C385FF5F-5EA1-478B-A930-54066C2F0B0F errorHandler: YES with WCErrorCodeTransferTimedOut -> IDSErrorTypeTimedOut -> IDSResponseTimedOut
Transfer timed out.