2015-09-30 47 views
1

我有一個數組存儲在我的i​​Phone上,無論何時在手機上更新後,我都需要將其發送到手錶中。我在RayWenderlich.com上關注了一個教程,但我似乎無法完成它的工作。爲什麼iPhone沒有將數組傳送給Apple Watch?

電話代碼:

import UIKit 
import Foundation 
import WatchConnectivity 

class ViewController: UIViewController, WCSessionDelegate { 

var array1 = ["Hi", "This", "Is", "A", "Test"]() 
var array2 = ["1", "2", "3", "4", "5"]() 

var session: WCSession? 

private func startSession() { 

    if WCSession.isSupported() { 

     session = WCSession.defaultSession() 
     session?.delegate = self 
     session?.activateSession() 

    } 

} 
private func sendToWatch() { 

    if let session = session where session.reachable { 

     session.transferUserInfo(["Array1": array1]) 

    } 

    if let session = session where session.reachable { 

     session.transferUserInfo(["Array2": array2]) 

    } 

} 

sendToWatch() 

} 

,觀看代碼:

import WatchKit 
import Foundation 
import WatchConnectivity 

var array1 = [String]() 

var array2 = [String]() 

class InterfaceController: WKInterfaceController, WCSessionDelegate { 

var session: WCSession? 

@IBOutlet var table: WKInterfaceTable! 

override func awakeWithContext(context: AnyObject?) { 
    super.awakeWithContext(context) 

    startSession() 

    table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

    var index = 0 

    while index < array1.count { 

     let row = table.rowControllerAtIndex(index) as! tableRowController 

     row.rowLabel.setText(array1[index]) 

     row.dateLabel.setText(array2[index]) 

     index++ 

    } 

} 

private func startSession() { 

    if WCSession.isSupported() { 

     session = WCSession.defaultSession() 
     session?.delegate = self 
     session?.activateSession() 

    } 

} 

func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) { 

    if let received1 = userInfo["Array1"] as? [String] { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      array1 = received1 
     }) 
    } 

    if let received2 = userInfo["Array2"] as? [String] { 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      array2 = received2 
     }) 
    } 

} 

} 

如果我輸入虛擬數據到陣列上的手錶的表工作正常,所以我知道一切都正確設置。我真的只有轉移/接收方面的問題。

第二次嘗試:

我現在試圖用updateApplicationContext()而不是transferUserInfo()。我刪除了session.reachable檢查並更改了一些代碼。

電話代碼:

private func sendToWatch() { 
do { 
     let applicationDict = ["Array1": array1] 
     let applicationDict2 = ["Array2": array2] 
     try WCSession.defaultSession().updateApplicationContext(applicationDict) 
     try WCSession.defaultSession().updateApplicationContext(applicationDict2) 
    } 

catch { 
     print(error) 
    } 
} 

關注代碼:

第三次嘗試:

我現在能夠有時得到要麼數組1或數組2至出現在手錶上。當然,它會崩潰應用程序,因爲兩個數組都沒有被成功接收。任何人都可以幫助我嗎?

關注代碼:當手表應用程序是在前臺

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) { 

    dispatch_async(dispatch_get_main_queue()) {() -> Void in 

     if let retrievedArray1 = applicationContext["Array1"] as? [String] { 

      array1 = retrievedArray1 

      print(array1) 

     } 

     if let retrievedArray2 = applicationContext["Array2"] as? [String] { 

      array2 = retrievedArray2 

      print(array2) 

     } 

     self.table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

     var index = 0 

     while index < array1.count { 

      let row = self.table.rowControllerAtIndex(index) as! tableRowController 

      row.rowLabel.setText(array1[index]) //My crash happens either here or.... 

      row.dateLabel.setText(array2[index]) //here because both arrays aren't being received and unreceived array is out of index 

      index++ 

     } 

    } 

} 
+0

你可以發佈你的會議爲iOS應用設置代碼嗎? – ccjensen

+0

謝謝,我剛剛做到了! – bkwebhero

+0

updateApplicationContext僅傳輸最近的字典,這是它的工作方式。你想使用transferUserInfo或者把array1和array2放到同一個字典中並調用updateApplicationContext一次 – ccjensen

回答

3

session.reachable只會是真實的(也有極少數例外)。

如果你想將數據發送到在後臺監視應用程序,你應該使用updateApplicationContexttransferUserInfotransferFile(你選擇哪一個取決於你正在發送和它的大小)。

因此,像:

響應第三屆編輯/問題的鼻祖更新代碼

電話代碼:

private func sendToWatch() { 
do { 
     let applicationDict = ["Array1": array1, "Array2": array2] 
     try WCSession.defaultSession().updateApplicationContext(applicationDict) 
    } 

catch { 
     print(error) 
    } 
} 

關注代碼:

func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) { 

    dispatch_async(dispatch_get_main_queue()) {() -> Void in 

     if let retrievedArray1 = applicationContext["Array1"] as? [String] { 

      array1 = retrievedArray1 

      print(array1) 

     } 

     if let retrievedArray2 = applicationContext["Array2"] as? [String] { 

      array2 = retrievedArray2 

      print(array2) 

     } 

     self.table!.setNumberOfRows(array1.count, withRowType: "tableRowController") 

     var index = 0 

     while index < array1.count { 

      let row = self.table.rowControllerAtIndex(index) as! tableRowController 

      row.rowLabel.setText(array1[index]) 

      row.dateLabel.setText(array2[index]) 

      index++ 

     } 

    } 
} 
+0

我剛剛更新了我的問題。仍然無法檢索數據。 – bkwebhero

+0

我已經更新了示例代碼,以顯示如何使用應用程序上下文來完成您正在嘗試執行的操作,儘管更可能的transferUserInfo是適合您的用例的那個 – ccjensen

4

隨着尊重你的第三次嘗試:

您不想使用updateApplicationContext - 您想使用transferUserInfo,如其他地方所建議的那樣。

每個updateApplicationContext調用都會覆蓋已經發送到手錶的任何先前數據。當您在dict1之後立即發送dict2時,第一個字典將被丟棄並替換爲dict2。您無法通過updateApplicationContext以這種方式獲取這兩個字典。

您將使用updateApplicationContext傳遞例如應用程序中只有最新設置很重要的設置或選項。例如,如果您有可在iOS應用程序中更改的標誌,則每次在iOS應用程序中更改標誌時都會使用updateApplicationContext。當watch app最終被加載時,它只會在didReceiveApplicationContext中看到該標誌的最後一個設置。

您的第三次嘗試的方式現在設置,第一個字典發送,然後緊接着第二個字典。在這兩本字典的交付中,您會看到基於變量滯後時間的間歇性故障。

如果didReceiveApplicationContext在第二個字典完全傳輸之前被調用,您將成功檢索字典1,因爲該數據尚未被覆蓋。它嘗試訪問索引「數組2」時會失敗,因爲它尚未存在。如果第二個上下文在手錶遇到檢索「Array 1」調用之前傳輸,那麼您的應用程序將在那裏失敗,因爲接收到的最後一個數據沒有鍵入「Array1」,而是「Array2」。

使用updateUserInfo的調用不會覆蓋前面的調用。當手表應用程序加載時,每次調用都會觸發didReceiveUserInfo代碼一次。通話的順序保持不變,所以如果您從iOS應用發送了dict1,dict2,然後dict3,手錶應用將按照該順序獲取它們。

+0

非常感謝。實際上,我確實通過在傳輸之前將兩個數組合併爲一個來實現didReceiveApplicationContext的工作。但我認爲我現在要按照你的方式去做,因爲我的解決方法很簡單。 – bkwebhero

相關問題