过去我主要使用ReactiveCocoa来简单地绑定视图和查看模型,现在我试图在整个新项目中尝试使用它但我遇到了麻烦让我的头围绕几件事。
我想做的就是这个 -
我花了一些时间探索像队列这样的选项,研究flatMap(.Latest)
这样的事情,但如果我完全诚实 - 我不知道我在做什么! :S
以下是一个非常基本的,愚蠢的实现,很快被黑客攻击,很可能很难实现。如果有人能给我一些指示我需要改变的东西,我将非常感激。我的doSomething
方法显然首先登录,但如果一次拨打多个电话,他们就不会等到第一个电话完成,因为我需要它们。
我可以使用loginValid
属性做点什么吗?
(另外,关于我应该如何构建这些东西的指针会很棒 - 我确定我用这段代码做了许多愚蠢的事情)
谢谢!
class FakeBackend: BackendType {
private var loginResponse = MutableProperty<LoginResponse?>(nil)
private let loginValid = MutableProperty<Bool>(false)
private var loginProducer: SignalProducer<LoginResponse, NSError>! // <-- implicitly unwrapped optional? Yuck
init() {
loginValid <~ loginResponse.producer.map { $0 != nil }
loginProducer = SignalProducer { [weak self] observer, disposable in
guard let _self = self else { return }
if let loginResponse = _self.loginResponse.value {
print("Already have login details")
observer.sendNext(loginResponse)
observer.sendCompleted()
} else {
print("Don't have login details, go get them")
_self.logIn().start(observer)
}
}
}
func doSomething() -> SignalProducer<HomeResponse, NSError> {
return loginProducer
.then(SignalProducer<HomeResponse, NSError> { observer, dispoable in
let homeResponse = HomeResponse(title: "My title is this")
observer.sendNext(homeResponse)
observer.sendCompleted()
})
}
private func logIn() -> SignalProducer<LoginResponse, NSError> {
return SignalProducer { observer, disposable in
print("Calling network login")
delayToMainThread(1.0, closure: { [weak self] () -> () in
guard let _self = self else { return }
let loginResponse = LoginResponse(accessToken: "MyAccessToken")
_self.loginResponse.value = loginResponse
observer.sendNext(loginResponse)
observer.sendCompleted()
})
}
}
}
答案 0 :(得分:0)
执行此操作的正确方法是replayLazily
,https://github.com/ReactiveCocoa/ReactiveCocoa/issues/2706
-replayLazily方便方法返回一个新的信号,当时 订阅后,将立即向订户发送整个历史记录 通过源信号的值,没有 重新执行源信号的订阅代码。
我收到了关于ReactiveCocoa Github问题页面的问题的回复。 {{3}}
基本上,你想做这样的事情 -
class FakeBackend: BackendType {
private var login: SignalProducer<LoginResponse, NSError>
init() {
login = SignalProducer { observer, disposable in
print("Logging in...")
// we'd actually make a network call here, but for demo purposes
// let's just return some dummy data.
let loginResponse = LoginResponse(accessToken: "MyAccessToken")
print("Logged in!")
observer.sendNext(loginResponse)
observer.sendCompleted()
}.replayLazily(1)
}
func loadHomeScreen() -> SignalProducer<HomeResponse, NSError> {
return login
.flatMap(.Latest, transform: homeResponse)
}
private func homeResponse(loginResponse: LoginResponse) -> SignalProducer<HomeResponse, NSError> {
return SignalProducer<HomeResponse, NSError> { observer, disposable in
print("Aaaand, we've gotten our HomeResponse.")
let homeResponse = HomeResponse(title: "My title is this")
observer.sendNext(homeResponse)
observer.sendCompleted()
}
}
}