【问题标题】:What is the right approach for resolving save operations with Swift Combine使用 Swift Combine 解决保存操作的正确方法是什么
【发布时间】:2020-03-09 10:02:59
【问题描述】:

我有一个典型的情况,我只想执行一次操作。例如使用 Swift Combine 更新数据库中的某些实体。我的问题是我真的不知道什么是只做一次的最佳方法。更新完成后如何退订?

这是通过我当前使用的层的代码 sn-p:

视图模型: 让 settingsModel: LocalSettingsModel

func saveLocalSettings(){
    let cancelable = settingsUseCase
                         .saveLocalSettings(localSettingsModel: settingsModel)
                         .sink(receiveCompletion: {_ in
                             print("Completed!!!")

                         }) { _ in
                             print("Result of Save operation!!!")
                         }
}

用例:

func saveLocalSettings(settings: LocalSettingsModel) -> AnyPublisher<LocalSettingsModel, Error> {
    return repository.saveLocalSettings(settings: settings)
}

存储库:

    guard let realmSettings = LocalSettingsRealmModel(fromModel: settings) else {
            return Fail<LocalSettingsModel, Error>(error: .postconditionError(errorMessage: ""))
                .eraseToAnyPublisher()
        }

    return self.localDataSource
        .saveLocalSettings(localSettings: realmSettings)
        .receive(on: DispatchQueue.main)
        .subscribe(on: DispatchQueue.global())
        .mapError { (error) -> Error in
             // do error mapping
        }
        .compactMap { settings in
            return (LocalSettingsModel(fromModel: settings))
        }
        .eraseToAnyPublisher()

数据来源:

func saveLocalSettings(localSettings: LocalSettingsRealmModel) -> AnyPublisher<LocalSettingsRealmModel, LocalDataSourceError> {
    do {
        return Just(try saveSettings(localSettings: localSettings))
            .mapError({ (Never) -> LocalDataSourceError in})
            .eraseToAnyPublisher()
    } catch let error as NSError {
        // return some error
    }
}

func saveSettings(localSettings: LocalSettingsRealmModel) throws -> LocalSettingsRealmModel
{
    let realm = try Realm()

    try realm.write {
        realm.add(localSettings, update: .modified)
    }

    return localSettings
}

当我们不期望反应世界中的连续信息流(例如旨在执行单个动作的函数的情况下)时,我真的很感激一些关于什么是好的实践方向的指示。我真的需要像在这个例子中那样使用 Just() 还是有办法从订阅者端处理这种情况。

【问题讨论】:

    标签: swift combine


    【解决方案1】:

    您想要将 Publisher 转换为单个值然后终止的东西,而 Combine 中的序列运算符就是您想要用于这种事情的东西。

    Combine 设置为处理一个或多个值。因此,作为消费者,如果您想使用assign 订阅者来设置一个值(或sink 订阅者来调用一个闭包,那么您需要给它一些方法来将潜在的多个值限制为一个值)在你的情况下做你的保存)。

    Combine 中的序列运算符是我想看的地方,但如果不知道有多少值以及如何选择应用哪个值,我无法真正描述 哪个。两个“简单”选项是firstlast,但有多种序列运算符可让您构建更复杂的选择(包括firstWherelastWhere,它们可让您根据自己的闭包确定,其中可以很方便。

    嵌入的链接都指向Using Combine 的在线/免费版本(披露:我写的)——虽然我没有任何关于序列运算符的明确示例,但我确实充实了参考细节他们在书中相当多。

    除非您明确地与发布商合作,否则您可能会发现使用 Promise 库更容易 - 取决于触发您保存的原因。我不知道 Realm 的最终目的是了解他们的 API 关注什么,以及您是否已经创建了生成数据的发布者,或者是否来自他们的 API - 因此您希望使用 Combine 来解决这个问题。

    【讨论】:

    • 用例是保存操作,所以我想发送保存请求并接收一些保存响应,我不希望有一个值流,只有一个,像响应一样的状态。在您看来,与传统的保存命令相比,使用 RX 有什么好处吗?如果有的话?
    • 对于单值响应,使用 RX 似乎过度使用 - 超出您的需要。 RX 主要面向处理多个响应,所以虽然你可以让它工作,但它比直接处理操作开销更大。
    猜你喜欢
    • 2012-10-10
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2013-10-27
    • 2014-04-08
    • 1970-01-01
    • 2014-12-08
    相关资源
    最近更新 更多