WatchConnectivity,如何在 iPhone 和 Apple Watch 之间共享数组
WatchConnectivity, How to Share an Array between iPhone and Apple Watch
我试图在 iPhone 和 Swift 4 中的 Apple Watch Apps 之间传递一个数组,到目前为止我一直没有成功。以下是我尝试遵循但未成功的一些示例。在这些示例中,它们不包含许多功能,但是当我尝试像这样编写它时,它会给出错误 does not conform to protocols
此外,当我声明 watch session 它没有正确声明时, didRecieveApplicationContext
在 swift 4 中与其他问题/示例 Link2
中显示的非常不同
这是我的 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()
}
}
这是 Apple Watch 控制器
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 相关的任何文档,因此,我们将不胜感激。
在WKInterfaceController
中:
我同意 Jens Peter 的评论,即您不应将 didReceiveApplicationContext
包装在 load() 函数中。
这样处理 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()
}
同时删除 awake(withContext)
中对 load()
的调用。
在 InterfaceController
中,将一些 print
语句放入 WCSession 存根中会很有帮助,即使您并未完全使用它们。您可以查看 WatchConnectivity 是否正在激活。[=33=]
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)")
}
您在 sessionDidDeactivate
中看到的这一行 WCSession.default.activate()
将允许在用户碰巧拥有多个手表的情况下支持多手表。
像在 WKInterfaceController
中那样删除 var watchSession: WCSession?
。再次在 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)
}
}
}
我认为这会稍微清理一下,希望能奏效或至少能推动你前进。但是,我没有在项目中构建它。希望这可以帮助。
我试图在 iPhone 和 Swift 4 中的 Apple Watch Apps 之间传递一个数组,到目前为止我一直没有成功。以下是我尝试遵循但未成功的一些示例。在这些示例中,它们不包含许多功能,但是当我尝试像这样编写它时,它会给出错误 does not conform to protocols
此外,当我声明 watch session 它没有正确声明时, didRecieveApplicationContext
在 swift 4 中与其他问题/示例
这是我的 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()
}
}
这是 Apple Watch 控制器
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 相关的任何文档,因此,我们将不胜感激。
在WKInterfaceController
中:
我同意 Jens Peter 的评论,即您不应将 didReceiveApplicationContext
包装在 load() 函数中。
这样处理 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()
}
同时删除 awake(withContext)
中对 load()
的调用。
在 InterfaceController
中,将一些 print
语句放入 WCSession 存根中会很有帮助,即使您并未完全使用它们。您可以查看 WatchConnectivity 是否正在激活。[=33=]
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)")
}
您在 sessionDidDeactivate
中看到的这一行 WCSession.default.activate()
将允许在用户碰巧拥有多个手表的情况下支持多手表。
像在 WKInterfaceController
中那样删除 var watchSession: WCSession?
。再次在 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)
}
}
}
我认为这会稍微清理一下,希望能奏效或至少能推动你前进。但是,我没有在项目中构建它。希望这可以帮助。