我的iPhone上存有一个数组,只要在手机上更新,我就需要在后台发送到手表。我已经关注了RayWenderlich.com的教程,但我似乎无法让它发挥作用。
电话代码:
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)
}
}
观看代码:
func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
//I can't figure out how to retrieve the data!
print(applicationContext) // returns nil
array1 = applicationContext["Array1"] as! [String] //returns nil and crashes app
array2 = applicationContext["Array2"] as! [String] //returns nil and crashes app
}
第三次尝试:
我现在能够有时让 array1或array2出现在Watch上。当然,它会崩溃应用程序,因为两个阵列都没有成功收到。有人可以帮我吗?
观察代码:
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 :(得分:4)
关于你的第三次尝试:
您不想使用updateApplicationContext - 您希望像其他人建议的那样使用transferUserInfo。
每个updateApplicationContext调用都将覆盖已发送到监视的任何先前数据。当您在dict1之后立即发送dict2时,第一个字典将被丢弃并替换为dict2。您无法通过updateApplicationContext以这种方式获取这两个词典。
您可以使用updateApplicationContext传递应用中的设置或选项,其中只有最新设置很重要。例如,如果您有一个可以在iOS应用程序中更改的标志,则每次在iOS应用程序中更改标志时都会使用updateApplicationContext。最终加载监视应用程序时,它只会在didReceiveApplicationContext中看到该标志的最后一个设置。
现在设置第三次尝试的方式,第一个dict被发送,然后紧接着第二个dict。您在基于这两个词典的交付中的可变延迟时间看到间歇性故障。
如果在完全传输第二个字典之前调用didReceiveApplicationContext,则您将成功检索字典1,因为该数据尚未被覆盖。它在尝试访问索引“数组2”时会失败,因为它还没有。如果在手表点击检索“阵列1”调用之前传输了第二个上下文,那么您的应用程序将在那里失败,因为收到的最后一个数据没有键入“Array1”,而是“Array2”。
使用updateUserInfo的调用不会覆盖先前的调用。加载监视应用程序时,它将为每次调用触发一次didReceiveUserInfo代码。调用的顺序是保持不变的,所以如果您从iOS应用程序发送了dict1,dict2和dict3,那么手表应用程序将按顺序获取它们。
答案 1 :(得分:3)
session.reachable只有在Watch应用程序位于前台时才会生效(有一些罕见的例外情况)。
如果您想在后台向观看应用发送数据,您应该使用updateApplicationContext
,transferUserInfo
或transferFile
(您选择哪一个取决于您发送的内容和它的大小)。
类似于:
更新了代码以响应发起人的第3次编辑/提问
电话代码:
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++
}
}
}