所以我正在学习如何为手机和手表设置 WCSession 委托。
我觉得我正在按照 Apple 文档的建议进行操作,但无论出于何种原因,我在控制台中收到此日志:“WCSession 缺少其委托。”我说日志而不是错误,因为我设置了我的委托来处理委托的activationDidCompleteWith函数中的错误,但该函数不会被命中。
知道我做错了什么吗?我正在使用 SwiftUI。
这是我手机端的代码:
PhoneMain.swift
import SwiftUI
import WatchConnectivity
@main
/// The main starting point for the phone app
struct PhoneMain: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
print("*** Phone Content View Appeared ***")
// Setting up phone default configurations
PhoneAppDefaults.sharedInstance.configure()
}
}
}
}
ContentView.swift
import SwiftUI
import WatchConnectivity
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
PhoneAppDefaults.swift
import Foundation
import WatchConnectivity
/// Where all of the phone app default configurations are setup
class PhoneAppDefaults {
/// The sharedInstance for the PhoneAppDefaults singleton
static var sharedInstance = PhoneAppDefaults()
/// Private init makes this struct a singleton
private init() {
print("*** WatchAppDefaults.sharedInstance initialized ***")
}
/// Initiaties default app configurations
func configure() {
print("*** Configuring watch defaults settings ***")
PhoneWCSessionDelegate().startSession()
}
}
PhoneWCSessionDelegate.swift
import Foundation
import WatchConnectivity
/// The WCSession delegate on the watch side
class PhoneWCSessionDelegate: NSObject, WCSessionDelegate {
/// Assigns this delegate to WCSession and starts the session
func startSession() {
guard WCSession.isSupported() else { return }
print("*** Starting WCSession for phone ***")
let session = WCSession.default
session.delegate = self
print("*** Activating phone WCSession ***")
session.activate()
}
/// A delegate function called everytime WCSession is activated
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
if let error = error {
print("*** Phone WCSession activation error: \(error) ***")
} else {
switch activationState {
case .activated:
print("*** WCSession activated for phone ***")
case .notActivated:
print("*** WCSession failed to activate for phone ***")
case .inactive:
print("*** WCSession inactive for phone ***")
@unknown default:
print("*** WCSession activation result: Unknown, for phone ***")
}
}
}
/// A delegate function called everytime WCSession recieves an application context update
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
print("*** WCSession recieved application context on phone ***")
}
/// A delegate function called everytime WCSession becomes inactive
func sessionDidBecomeInactive(_ session: WCSession) {
print("*** WCSession became inactive on phone ***")
}
/// A delegate function called everytime WCSession deactivates
func sessionDidDeactivate(_ session: WCSession) {
print("*** WCSession deactivated on phone ***")
}
}
这是手表的一面:
WatchMain.swift
import SwiftUI
import WatchConnectivity
@main
/// The main starting point for the watch app
struct WatchMain: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
print("*** Watch Content View Appeared ***")
// Setting up watch default configurations
WatchAppDefaults.sharedInstance.configure()
}
}
}
}
ContentView.swift
import SwiftUI
import WatchConnectivity
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
WatchAppDefaults.swift
import Foundation
import WatchConnectivity
/// Where all of the watch app default configurations are setup
class WatchAppDefaults {
/// The sharedInstance for the WatchAppDefaults singleton
static var sharedInstance = WatchAppDefaults()
/// Private init makes this struct a singleton
private init() {
print("*** WatchAppDefaults.sharedInstance initialized ***")
}
/// Initiaties default app configurations
func configure() {
print("*** Configuring watch defaults settings ***")
WatchWCSessionDelegate().startSession()
}
}
WatchWCSessionDelegate.swift
import Foundation
import WatchConnectivity
/// The WCSession delegate on the watch side
class WatchWCSessionDelegate: NSObject, WCSessionDelegate {
/// Assigns this delegate to WCSession and starts the session
func startSession() {
print("*** Starting WCSession for watch ***")
let session = WCSession.default
session.delegate = self
print("*** Activating watch WCSession ***")
session.activate()
}
/// A delegate function called everytime WCSession is activated
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
if let error = error {
print("*** Watch WCSession activation error: \(error) ***")
} else {
switch activationState {
case .activated:
print("*** WCSession activated for watch ***")
case .notActivated:
print("*** WCSession failed to activate for watch ***")
case .inactive:
print("*** WCSession inactive for watch ***")
@unknown default:
print("*** WCSession activation result: Unknown, for watch ***")
}
}
}
/// A delegate function called everytime WCSession recieves an application context update
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
print("*** WCSession recieved application context on watch ***")
}
}
根据 @jnpdx 的建议,委托被启动,然后从范围中删除。通过将委托作为属性添加到我的单例中,委托能够保留在范围内,从而消除控制台向我发出的不存在委托的通知。