ios 将 Package 在AnyPublisher中的CurrentValueSubject值传递给另一个类

kgqe7b3p  于 2023-06-07  发布在  iOS
关注(0)|答案(1)|浏览(199)

给你看我的代码:

protocol SomeProtocol {
    var isLocalNotificationsEnabledPublisher: AnyPublisher<Bool, Error> { get }
    
    func saveLocalNotifications(_ enabled: Bool) throws
}

final class UserSettingsClass {
    private var repository: CoreDataRepo
    
    private var isLocalNotificationsEnabledSubject = CurrentValueSubject<Bool, Error>(false) 
// I make it private so that no other classes can change it from outside,
// I can only subscribe on its values.
    
    private var cancellables = Set<AnyCancellable>()
    
    init(repository: CoreDataRepo) {
        self.repository = repository
        binding()
    }
}

extension UserSettingsClass: SomeProtocol {
    var isLocalNotificationsEnabledPublisher: AnyPublisher<Bool, Error> {
        return isLocalNotificationsEnabledSubject.eraseToAnyPublisher()
    }

    func saveLocalNotifications(_ enabled: Bool) throws {
        var userSettings = userSettings // this is core data object... 
        
        userSettings?.isLocalNotificationsEnabled = enabled 
// this is the important part, it has this toggle.
// I need to be able to send this value to my LocalNotificaitonsService class and based
// on this value understand whether I can send local notifications or not.
        
        if isLocalNotificationsEnabledSubject.value != enabled {
            throw someError
        }
        
        isLocalNotificationsEnabledSubject.send(userSettings?.isLocalNotificationsEnabled ?? false)
    }
}

下面是我如何将它绑定到我的发布者,以便我可以订阅我在saveLocalNotifications方法中发送的值:

private func binding() {
        isLocalNotificationsEnabledPublisher
            .sink(
                receiveCompletion: { _ in },
                receiveValue: { [weak self] value in
                    do {
                        try saveLocalNotifications(value) // recursion here + not handling error properly...
                    } catch {
                        return
                    }
                }
                
            ).store(in: &cancellables)
    }

这段代码会导致递归,导致我的应用程序崩溃。以下是我在本地通知管理器中尝试使用它的方式:

private let isLocalNotificationsEnabledPublisher: AnyPublisher<Bool, Error>
    
private var cancellables = Set<AnyCancellable>()
    
public init(isLocalNotificationsEnabledPublisher: AnyPublisher<Bool, Error>) {
        self.isLocalNotificationsEnabledPublisher = isLocalNotificationsEnabledPublisher
    }
extension LocalNotificationsManager: SomeOtherProtocol {
    public func requestNotificationAuthorization() throws {
        isLocalNotificationsEnabledPublisher
            .sink(
                receiveCompletion: { _ in },
                receiveValue: { [weak self] value in
                    if value == true {
                        Task {
                            try await self?.center.requestAuthorization(options: [.badge, .sound, .alert])
                        }
                    }
                }
            ).store(in: &cancellables)
    }

因此,基本上这段代码不能正常工作,因为我不明白如何在本地通知管理器类中获取主题值。我需要能够从用户设置的切换值下沉,并决定我是否可以或不能发送本地通知。先谢谢你。

qq24tv8q

qq24tv8q1#

你有递归,因为你调用saveLocalNotifications,然后再次触发合并链,因为这反过来又调用isLocalNotificationsEnabledSubject.send(...)
要防止递归,可以在订阅isLocalNotificationsEnabledSubject的合并链中使用removeDuplicates
也就是说,您可能希望重新考虑您的体系结构,以便不可能进行递归。

相关问题