-
-
Save dodikk/b547701f0dbad794d33f2ad1c198e1e5 to your computer and use it in GitHub Desktop.
| PKLoginModelPromise.swift:62:22: error: enum element 'main' cannot be referenced as an instance member | |
| .onFail(.main, block: | |
| ^ |
| github "FutureKit/FutureKit" "v3" | |
| github "ReSwift/ReSwift" == 3.0.0 | |
| github "ReSwift/ReSwiftRouter" == 0.5.1 |
| public class PKLoginModelPromise : PKLoginModel | |
| { | |
| private let reduxStore: PKAppStateStore | |
| private let networkLoader: PKLoginService | |
| private let tokenRepo: PKAccessTokenRepo | |
| public init(withReduxStore reduxStore: PKAppStateStore, | |
| networkLoader: PKLoginService, | |
| tokenRepo: PKAccessTokenRepo) | |
| { | |
| self.reduxStore = reduxStore | |
| self.networkLoader = networkLoader | |
| self.tokenRepo = tokenRepo | |
| } | |
| public func loginAsync( | |
| _ email: String, | |
| password: String) | |
| { | |
| let loginFromNetFuture: FetchAccessTokenFuture = | |
| LoginFutures.login( | |
| withService: self.networkLoader, | |
| email: email, | |
| password: password) | |
| let tokenRepo = self.tokenRepo | |
| let reduxStore = self.reduxStore | |
| loginFromNetFuture.onSuccess(.background, block: | |
| { | |
| tokenFromNet in | |
| let storeLoginFuture = PKAccessTokenRepoFutures.storeToken(tokenFromNet, inRepo: tokenRepo) | |
| return storeLoginFuture | |
| }) | |
| .onSuccess(.main, block: | |
| { | |
| tokenFromDisk in | |
| let action = UpdateAccessTokenAction(accessToken: tokenFromDisk) | |
| reduxStore.dispatch(action) | |
| return tokenFromDisk | |
| }) | |
| .onFail(.main, block: | |
| { | |
| diskError in | |
| let action = LoginErrorAction(error: diskError) | |
| self.reduxStore.dispatch(action) | |
| return diskError | |
| }) | |
| } | |
| } |
So the latest version of the onFail() handler typically does NOT return any values.
It doesn't 're-map' the future into a new Future (unlike onSuccess or onComplete).
This is different than javascript Promises 'catch' which by default 'eats' the error. And then leads to confusion and complexity.
So in FutureKit onFail() will let you handle errors, but it still always returns the same 'Failed' Future. Which will usually lead to more reliable error handling.
onFail() allows you to add 'side' effects when a Future fails, but it always returns the same failed 'Future'. So you usually just return Void.
If you want to 'eat' or modify the Failed Future, use 'onComplete' or 'mapError'.
So try removing the return diskError
.onFail(.main, block:
{
diskError in
let action = LoginErrorAction(error: diskError)
self.reduxStore.dispatch(action)
})
The Swift type inference machine can be fickle, and when it gets confused it can lead to confusing errors.
if that doesn't help... sometimes it can help to formally declare the return values for onSuccess, since it uses helps the compiler figure out 'which' onSuccess or onComplete method to bind to.
public class PKLoginModelPromise : PKLoginModel
{
private let reduxStore: PKAppStateStore
private let networkLoader: PKLoginService
private let tokenRepo: PKAccessTokenRepo
public init(withReduxStore reduxStore: PKAppStateStore,
networkLoader: PKLoginService,
tokenRepo: PKAccessTokenRepo)
{
self.reduxStore = reduxStore
self.networkLoader = networkLoader
self.tokenRepo = tokenRepo
}
public func loginAsync(
_ email: String,
password: String)
{
let loginFromNetFuture: FetchAccessTokenFuture =
LoginFutures.login(
withService: self.networkLoader,
email: email,
password: password)
let tokenRepo = self.tokenRepo
let reduxStore = self.reduxStore
loginFromNetFuture.onSuccess(.background)
{
tokenFromNet -> Future<Token> in // idk what type PKAccessTokenRepoFutures.storeToken returns so I'm guessing it's something.
return PKAccessTokenRepoFutures.storeToken(tokenFromNet, inRepo: tokenRepo)
}
.onSuccess(.main) {
tokenFromDisk -> Token in // adding return type again
let action = UpdateAccessTokenAction(accessToken: tokenFromDisk)
reduxStore.dispatch(action)
return tokenFromDisk
}
.onFail(.main)
{
diskError -> Void in // onFail works better as Void!
let action = LoginErrorAction(error: diskError)
self.reduxStore.dispatch(action)
}
}
}
So try removing the return diskError
I still had similar errors even without a return statement.
if that doesn't help... sometimes it can help to formally declare the return values for onSuccess
And this has solved my issue. Thanks a lot for responding so quickly.
tokenFromNet -> Future<Token> in
tokenFromDisk -> Token in // adding return type again
I'm trying to chain the futures following the example from the FutureKit readme.