为什么 iPhone 不将数组传输到 Apple Watch?
Why isn't iPhone transferring an array to Apple Watch?
我的 iPhone 上存储了一个数组,每当它在 phone 上更新时,我都需要在后台将其发送到 Watch。我遵循了 RayWenderlich.com 上的教程,但我似乎无法让它发挥作用。
Phone代码:
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
})
}
}
}
如果我在数组中输入虚拟数据,手表上的 Table 工作正常,所以我知道一切设置正确。我真的只有 Transfer/Receiving.
有问题
第二次尝试:
我现在尝试使用 updateApplicationContext()
而不是 transferUserInfo()
。我删除了 session.reachable
检查并更改了一些代码。
Phone代码:
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 出现在手表上。当然,它会使应用程序崩溃,因为两个数组均未成功接收。有人可以帮我解决这个问题吗?
观看代码:
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++
}
}
}
session.reachable 仅当 Watch 应用程序在前台时才为真(有一些罕见的例外)。
如果你想在后台向手表应用程序发送数据,你应该使用updateApplicationContext
、transferUserInfo
或transferFile
(你选择哪个取决于你是什么发送及其大小)。
所以像这样:
更新代码以响应发起者
的第 3 个 edit/question
Phone代码:
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++
}
}
}
关于您的第三次尝试:
您不想使用 updateApplicationContext - 您想要使用 transferUserInfo,正如其他地方所建议的那样。
每次 updateApplicationContext 调用都会覆盖之前已发送到手表的所有数据。当您在 dict1 之后立即发送 dict2 时,第一个字典将被丢弃并替换为 dict2。您不能以这种方式通过 updateApplicationContext 获取两个词典。
例如,您可以使用 updateApplicationContext 传递应用中的设置或选项,其中只有最新的设置很重要。例如,如果您有一个可以在 iOS 应用程序中更改的标志,则每次在 iOS 应用程序中更改该标志时,您都将使用 updateApplicationContext。当 watch 应用程序最终加载时,它只会看到 didReceiveApplicationContext 中标志的最后设置。
现在设置第三次尝试的方式是发送第一个指令,然后立即发送第二个指令。在交付这两个词典时,您会看到基于可变滞后时间的间歇性故障。
如果在第二个字典完全传输之前调用 didReceiveApplicationContext,您将成功检索字典 1,因为该数据尚未被覆盖。当它试图访问索引 "Array 2" 时会失败,因为它还不存在。如果第二个上下文在手表点击检索 "Array 1" 调用之前传输,那么您的应用程序将在那里失败,因为最后接收到的数据不是在 "Array1" 上输入,而是在 "Array2".[= 上输入10=]
使用 updateUserInfo 的调用不会覆盖之前的调用。当手表应用程序加载时,它会在每次调用时触发一次 didReceiveUserInfo 代码。调用顺序保持不变,因此如果您从 iOS 应用程序发送 dict1、dict2 和 dict3,手表应用程序将按此顺序获取它们。
我的 iPhone 上存储了一个数组,每当它在 phone 上更新时,我都需要在后台将其发送到 Watch。我遵循了 RayWenderlich.com 上的教程,但我似乎无法让它发挥作用。
Phone代码:
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
})
}
}
}
如果我在数组中输入虚拟数据,手表上的 Table 工作正常,所以我知道一切设置正确。我真的只有 Transfer/Receiving.
有问题第二次尝试:
我现在尝试使用 updateApplicationContext()
而不是 transferUserInfo()
。我删除了 session.reachable
检查并更改了一些代码。
Phone代码:
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 出现在手表上。当然,它会使应用程序崩溃,因为两个数组均未成功接收。有人可以帮我解决这个问题吗?
观看代码:
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++
}
}
}
session.reachable 仅当 Watch 应用程序在前台时才为真(有一些罕见的例外)。
如果你想在后台向手表应用程序发送数据,你应该使用updateApplicationContext
、transferUserInfo
或transferFile
(你选择哪个取决于你是什么发送及其大小)。
所以像这样:
更新代码以响应发起者
的第 3 个 edit/questionPhone代码:
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++
}
}
}
关于您的第三次尝试:
您不想使用 updateApplicationContext - 您想要使用 transferUserInfo,正如其他地方所建议的那样。
每次 updateApplicationContext 调用都会覆盖之前已发送到手表的所有数据。当您在 dict1 之后立即发送 dict2 时,第一个字典将被丢弃并替换为 dict2。您不能以这种方式通过 updateApplicationContext 获取两个词典。
例如,您可以使用 updateApplicationContext 传递应用中的设置或选项,其中只有最新的设置很重要。例如,如果您有一个可以在 iOS 应用程序中更改的标志,则每次在 iOS 应用程序中更改该标志时,您都将使用 updateApplicationContext。当 watch 应用程序最终加载时,它只会看到 didReceiveApplicationContext 中标志的最后设置。
现在设置第三次尝试的方式是发送第一个指令,然后立即发送第二个指令。在交付这两个词典时,您会看到基于可变滞后时间的间歇性故障。
如果在第二个字典完全传输之前调用 didReceiveApplicationContext,您将成功检索字典 1,因为该数据尚未被覆盖。当它试图访问索引 "Array 2" 时会失败,因为它还不存在。如果第二个上下文在手表点击检索 "Array 1" 调用之前传输,那么您的应用程序将在那里失败,因为最后接收到的数据不是在 "Array1" 上输入,而是在 "Array2".[= 上输入10=]
使用 updateUserInfo 的调用不会覆盖之前的调用。当手表应用程序加载时,它会在每次调用时触发一次 didReceiveUserInfo 代码。调用顺序保持不变,因此如果您从 iOS 应用程序发送 dict1、dict2 和 dict3,手表应用程序将按此顺序获取它们。