如何“转发” @Published值

时间:2020-01-02 19:22:42

标签: swiftui combine

我对SwiftUI和Combine还是很陌生,尽管我在Swift方面有丰富的经验,并且对ReactiveKit有所了解,但我发现很难使一些基本的东西正常工作。

例如,我尝试在ViewModel上添加一个isLoggedIn属性,该属性应简单地“转发” UserManager类的isLoggedIn属性。使用ReactiveKit,这相当琐碎,但是使用SwiftUI / Combine,我无法正常工作。该值仅设置一次,然后再也不会更新。

class UserManager: ObservableObject {
  @Published private(set) var isLoggedIn = false

  // This class has all the actual logic for logging in, 
  // keeping track of the logged in user and the auth status, etc.
}

class ViewModel: ObservableObject {
  @Published var isLoggedIn = false

  private let userManager: UserManager

  init(userManager: UserManager) {
    self.userManager = userManager
    isLoggedIn = userManager.isLoggedIn // <- this doesn't work
    userManager.$isLoggedIn.assign(to: \.isLoggedIn, on: self) // <- neither does this
  }

  func logout() {
    userManager.logout()
  }
}

struct ContentView: View  {
  @ObservedObject var viewModel: ViewModel

  var body: some View {
    // this will use viewModel.isLoggedIn at some point
  }
}

2 个答案:

答案 0 :(得分:1)

以下应能工作。如果您不存储订户,则会自动取消。

  private var subscribers = [AnyCancellable]()
  init(userManager: UserManager) {
    self.userManager = userManager
    userManager.$isLoggedIn
       .assign(to: \.isLoggedIn, on: self)
       .store(in: &subscribers) // << subscriber must be kept
  }

答案 1 :(得分:0)

另一种方法是将ViewModel中的@Published var isLoggedIn替换为手动objectWillChange。

class ViewModel: ObservableObject {
  var isLoggedIn: Bool {userManager.isLoggedIn}

  private let userManager: UserManager
  private var anyCancellable: AnyCancellable?

  init(userManager: UserManager) {
    self.userManager = userManager

    anyCancellable = userManager.objectWillChange.sink {[weak self] _ in
      self?.objectWillChange.send()
    }
  }

}