2017-10-19 114 views
2

我正嘗試在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() –

回答

1

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) 
    } 
} 
} 

我認爲它清理了一下,並希望工作或至少前進你。然而,我沒有在一個項目中構建這個。希望這可以幫助。