使用 SwiftUI 设置 WCSessionDelegate 的问题

问题描述 投票:0回答:1

所以我正在学习如何为手机和手表设置 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 ***")
        
    }
}
ios swiftui delegates watchos wcsession
1个回答
0
投票

根据 @jnpdx 的建议,委托被启动,然后从范围中删除。通过将委托作为属性添加到我的单例中,委托能够保留在范围内,从而消除控制台向我发出的不存在委托的通知。

© www.soinside.com 2019 - 2024. All rights reserved.