我很久以前做过一个例子,如何使用 Swift 从 iPhone 向 Apple Watch 发送一条简单的消息:
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
// MARK: Outlets
@IBOutlet weak var textField: UITextField!
// MARK: Variables
var wcSession : WCSession! = nil
// MARK: Overrides
override func viewDidLoad() {
super.viewDidLoad()
wcSession = WCSession.default
wcSession.delegate = self
wcSession.activate()
}
// MARK: Button Actions
@IBAction func sendText(_ sender: Any) {
let txt = textField.text!
let message = ["message":txt]
wcSession.sendMessage(message, replyHandler: nil) { (error) in
print(error.localizedDescription)
}
}
// MARK: WCSession Methods
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
// Code
}
func sessionDidBecomeInactive(_ session: WCSession) {
// Code
}
func sessionDidDeactivate(_ session: WCSession) {
// Code
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试使用 SwiftUI 做同样的事情,但到目前为止没有成功。任何人都可以帮助解决这个问题吗?
我只需要知道如何在 SwiftUI 中使用 WCSession 类和 WCSessionDelegate。
谢谢
Kev*_*inP 15
我刚和你有同样的问题,我想通了:
首先,您需要实现一个符合WCSessionDelegate. 我喜欢为此使用一个单独的类:
import WatchConnectivity
class ConnectivityProvider: NSObject, WCSessionDelegate {
private let session: WCSession
init(session: WCSession = .default) {
self.session = session
super.init()
self.session.delegate = self
}
func send(message: [String:Any]) -> Void {
session.sendMessage(message, replyHandler: nil) { (error) in
print(error.localizedDescription)
}
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
// code
}
func sessionDidBecomeInactive(_ session: WCSession) {
// code
}
func sessionDidDeactivate(_ session: WCSession) {
// code
}
}
Run Code Online (Sandbox Code Playgroud)
现在您需要一个 ViewModel 将您的 ConnectivityProvider 作为参数。ViewModel 将负责您的 View 和 ConnectivityProvider 的连接。它还保存稍后在您的视图中定义的文本字段的值。
import SwiftUI
final class ViewModel: ObservableObject {
private(set) var connectivityProvider: ConnectivityProvider
var textFieldValue: String = ""
init(connectivityProvider: ConnectivityProvider) {
self.connectivityProvider = connectivityProvider
}
func sendMessage() -> Void {
let txt = textFieldValue
let message = ["message":txt]
connectivityProvider.send(message: message)
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以构建一个简单的视图,它由一个文本字段和一个按钮组成。您的 View 将依赖于您刚刚定义的 ViewModel。
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
TextField("Message Content", text: $viewModel.textFieldValue)
Button(action: {
self.viewModel.sendMessage()
}) {
Text("Send Message")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的是,您需要在 SceneDelegate 中组合您的 ConnectivityProvider、ViewModel 和 View:
let viewModel = ViewModel(connectivityProvider: ConnectivityProvider())
let contentView = ContentView(viewModel: viewModel)
...
window.rootViewController = UIHostingController(rootView: contentView)
Run Code Online (Sandbox Code Playgroud)
==================================
更新:如何激活会话?
首先向您的 ConnectivityProvider 添加一个激活会话的新函数:
class ConnectivityProvider: NSObject, WCSessionDelegate {
...
func connect() {
guard WCSession.isSupported() else {
print("WCSession is not supported")
return
}
session.activate()
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在需要连接 WCSession 时调用 connect 函数。你应该能够在任何地方连接它,比如在你的 SceneDelegate 中,在你的 ViewModel 中,甚至直接在你的 ConnectivityProvider 的 init 中:
连接提供者初始化:
class ConnectivityProvider: NSObject, WCSessionDelegate {
private let session: WCSession
init(session: WCSession = .default) {
self.session = session
super.init()
self.session.delegate = self
self.connect()
}
...
}
Run Code Online (Sandbox Code Playgroud)
视图模型:
import SwiftUI
final class ViewModel: ObservableObject {
private(set) var connectivityProvider: ConnectivityProvider
var textFieldValue: String = ""
init(connectivityProvider: ConnectivityProvider) {
self.connectivityProvider = connectivityProvider
self.connectivityProvider.connect()
}
func sendMessage() -> Void {
let txt = textFieldValue
let message = ["message":txt]
connectivityProvider.send(message: message)
}
}
Run Code Online (Sandbox Code Playgroud)
场景委托:
let connectivityProvider = ConnectivityProvider()
connectivityProvider.connect()
let viewModel = ViewModel(connectivityProvider: connectivityProvider)
let contentView = ContentView(viewModel: viewModel)
...
window.rootViewController = UIHostingController(rootView: contentView)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1984 次 |
| 最近记录: |