WatchConnectivity,如何在iPhone和Apple Watch之间共享阵列

WatchConnectivity,如何在iPhone和Apple Watch之间共享阵列

问题描述:

我正尝试在Swift 4中传递iPhone和Apple Watch应用程序之间的阵列,至此我一直不成功。以下是我试图遵循的一些例子,但未成功。在这些例子中,它们不包含许多功能,但是当我尝试写它时,它会给出错误does not conform to protocols另外,当我宣布观看会话时它并没有正确声明,didRecieveApplicationContext在swift中也有很大不同4比其他问题如/例子LinkLink2WatchConnectivity,如何在iPhone和Apple Watch之间共享阵列

这里是我的iPhone的ViewController

import UIKit 
import WatchConnectivity 

class watchtimetablemaker: UIViewController, WCSessionDelegate { 

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 
} 

func sessionDidBecomeInactive(_ session: WCSession) { 
} 

func sessionDidDeactivate(_ session: WCSession) { 
} 


var watchSession: WCSession? 
var initalArray = [String]() 
var combination = "" 
var vdlArray = [String]() 


@IBAction func Save(_ sender: Any) { 

    vdlArray.removeAll() 

//here I edit the arrays, add instances etc. cut out for fluency 

    self.view.endEditing(true) 

    sendToWatch() 

    UserDefaults.standard.set(vdlArray, forKey: "vdlarray") 
    UserDefaults.standard.synchronize() 

    print(initalArray) 
    print(vdlArray) 

} 

func sendToWatch(){ 
    do{ 
     let appDictionary = ["Array": initalArray] 
     try WCSession.default.updateApplicationContext(appDictionary) 
    } 
    catch { 
     print(error) 
    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    if (WCSession.isSupported()){ 
     watchSession = WCSession.default 
     watchSession?.delegate = self 
     watchSession?.activate() 
    } 

    vdlArray = UserDefaults.standard.array(forKey: "vdlarray") as! [String] 

    print(vdlArray) 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 
} 

这里是苹果观看控制器

import WatchKit 
import Foundation 
import WatchConnectivity 


class TimetableWatch: WKInterfaceController, WCSessionDelegate { 

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 
    load() 
} 

@IBOutlet var tabletitle: WKInterfaceTable! 
var watchSession: WCSession? 
var tableData = [String]() 

override func awake(withContext context: Any?) { 
    super.awake(withContext: context) 

    if (WCSession.isSupported()){ 
     watchSession = WCSession.default 
     watchSession?.delegate = self 
     watchSession?.activate() 
    } 

    load() 

    tabletitle.setNumberOfRows(tableData.count, withRowType: "Cell") 

    var i = 0 
    for item in tableData { 
     let row = tabletitle.rowController(at: i) as! TableCellRow 

     row.tbalecelllabel.setText(item) 

     i = i + 1 
    } 
} 

func load(){ 

    func session(session: WCSession, didRecieveApplicationContext applicationContext: [String : Any]) { 

     DispatchQueue.main.async() {() -> Void in 
      if let retreivedArray = applicationContext["Array"] as? [String] { 
       self.tableData = retreivedArray 
       print(self.tableData) 
      } 
     } 
    } 
} 

override func willActivate() { 
    super.willActivate() 
} 

override func didDeactivate() { 
    super.didDeactivate() 
} 
} 

我一直无法找到任何有关swift4的文档,所以任何帮助将不胜感激。

+0

我还没有使用Swift 4(但),但它看起来很奇怪,你的didReceiveApplicationContext函数被包装在load()函数中。你可以像这样声明WCSession:let session = WCSession.default() –

WKInterfaceController

我从延彼得的评论表示赞同,你不应该在load()函数包装didReceiveApplicationContext。在activationDidCompleteWith

处理错误这样:

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 
    if let error = error { 
     print("Activation failed with error: \(error.localizedDescription)") 
     return 
    } 
    print("Watch activated with state: \(activationState.rawValue)") 
} 

这也将有助于确定WatchConnectivity甚至变得成立。

删除var watchSession: WCSession?完全和awake(withContext)声明WCSession为:

if WCSession.isSupported() { 
     let watchSession = WCSession.default 
     watchSession = self 
     watchSession() 
    } 

同时删除调用load()awake(withContext)

InterfaceController中,将一些print语句放入WCSession存根是有帮助的,即使您没有完全使用它们也是如此。您可以查看WatchConnectivity是否正在激活。

func sessionDidBecomeInactive(_ session: WCSession) { 
    // To support multiple watches. 
    print("WC Session did become inactive.") 
} 

func sessionDidDeactivate(_ session: WCSession) { 
    // To support multiple watches. 
    WCSession.default.activate() 
    print("WC Session did deactivate.") 
} 

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 
    if let error = error { 
     print("WC Session activation failed with error: \(error.localizedDescription)") 
     return 
    } 
    print("Phone activated with state: \(activationState.rawValue)") 
} 

此行WCSession.default.activate()如您在sessionDidDeactivate看到将允许在用户恰好有一个以上的手表关闭的情况下多表支持。

删除var watchSession: WCSession?就像在WKInterfaceController中做的那样。再次viewDidLoad()支票WCSession支持有:

if WCSession.isSupported() { 
     let watchSession = WCSession.default 
     watchSession = self 
     watchSession() 
    } 

更新sendToWatch()到:

func sendToWatch() { 
let session = WCSession.default() 

if session.activationState == .activated { 
    let appDictionary = ["Array": initalArray] 
do { 
    try session.updateApplicationContext(appDictionary) 
} catch { 
    print(error) 
    } 
} 
} 

我认为它清理了一下,并希望工作或至少前进你。然而,我没有在一个项目中构建这个。希望这可以帮助。