最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Observing voiceover changes on Mac - Swift 6 migration issues - Stack Overflow

programmeradmin1浏览0评论

I am listening to voiceover changes through NSWorkspace KVO and here is my code

public final class MyContext: ObservableObject {
    public weak var actionHandler: ActionHandler?
    public weak var dataProvider: DataProvider?

    @Published public private(set) var isVoiceoverEnabled: Bool
    @objc private var voiceOverObserver: NSKeyValueObservation?

    public init(
        actionHandler: ActionHandler,
        dataProvider: DataProvider
    ) {
        self.actionHandler = actionHandler
        self.dataProvider = dataProvider
        self.isVoiceoverEnabled = NSWorkspace.shared.isVoiceOverEnabled
        self.voiceOverObserver = NSWorkspace.shared.observe(\.isVoiceOverEnabled) { [weak self] _, _ in
            self?.updateVoiceOverState()
        }
    }

    @objc
    private func updateVoiceOverState() {
        if isVoiceoverEnabled != NSWorkspace.shared.isVoiceOverEnabled {
            isVoiceoverEnabled = NSWorkspace.shared.isVoiceOverEnabled
        }
    }
}

I am in the process of migrating the app to Swift 6 and I am having some trouble fixing the issues in this class.

The compiler complains that the class is not Sendable

Swift 6 concurrency requires that everyhing needs to be isolated to an actor or sendable across different contexts (please correct me if I am wrong) So, this error is telling me that the callback block can be called from any context and I either have to isolate it to MainActor or make the class Sendable.

I tried to make the class Sendable but ran into issues since I have weak vars defined.

When I try to isolate the class to MainActor I run into a different issue

What am I missing here? How do I fix this?

I am trying to learn Swift concurrency in this process and any help here would be very much appreciated!

I am listening to voiceover changes through NSWorkspace KVO and here is my code

public final class MyContext: ObservableObject {
    public weak var actionHandler: ActionHandler?
    public weak var dataProvider: DataProvider?

    @Published public private(set) var isVoiceoverEnabled: Bool
    @objc private var voiceOverObserver: NSKeyValueObservation?

    public init(
        actionHandler: ActionHandler,
        dataProvider: DataProvider
    ) {
        self.actionHandler = actionHandler
        self.dataProvider = dataProvider
        self.isVoiceoverEnabled = NSWorkspace.shared.isVoiceOverEnabled
        self.voiceOverObserver = NSWorkspace.shared.observe(\.isVoiceOverEnabled) { [weak self] _, _ in
            self?.updateVoiceOverState()
        }
    }

    @objc
    private func updateVoiceOverState() {
        if isVoiceoverEnabled != NSWorkspace.shared.isVoiceOverEnabled {
            isVoiceoverEnabled = NSWorkspace.shared.isVoiceOverEnabled
        }
    }
}

I am in the process of migrating the app to Swift 6 and I am having some trouble fixing the issues in this class.

The compiler complains that the class is not Sendable

Swift 6 concurrency requires that everyhing needs to be isolated to an actor or sendable across different contexts (please correct me if I am wrong) So, this error is telling me that the callback block can be called from any context and I either have to isolate it to MainActor or make the class Sendable.

I tried to make the class Sendable but ran into issues since I have weak vars defined.

When I try to isolate the class to MainActor I run into a different issue

What am I missing here? How do I fix this?

I am trying to learn Swift concurrency in this process and any help here would be very much appreciated!

Share Improve this question asked Mar 12 at 22:06 rottweilerrottweiler 1,2231 gold badge12 silver badges23 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Making the whole class bounds to any global actors is an approach, for example @MainActor:

@MainActor
public final class MyContext: ObservableObject {
    public init(...) {
        ...
        self.voiceOverObserver = NSWorkspace.shared.observe(\.isVoiceOverEnabled) { [weak self] _, _ in
            Task { @MainActor in
                self?.updateVoiceOverState()
            }
        }
    }
}
发布评论

评论列表(0)

  1. 暂无评论