Reputation: 8002
In my app's networking class, I follow the typical closure model, in which you pass a result to a completion closure.
class func login(username: String, password: String, completion: @escaping (Result) -> Void){
...
let user = makeUserWithSomeData()
completion(Result.Success(user))
}
The result can be either Success, which includes any data I wish to return, and Failure, which includes an error message.
enum Result {
case Success(Any)
case Failure(String)
}
A call looks like this:
MyWebServices.login(username: username, password: password)
{ (result) in
switch(result)
{
case .Success(let value):
print("Success:\n\(value)")
if let user = value as? User {
useMyValue(user)
}
break
case .Failure(let error):
print("Error: \(error)")
break;
}
}
The problem is that value
is type Any, and needs to be cast with an if let
statement. This can get a little ugly if Success is sending back a dictionary, and isn't very flexible (what if someone changes a key later?). Is there any way to have the value Success passes back be a little smarter and remember the type of what was assigned to it?
Upvotes: 0
Views: 44
Reputation: 19156
How about this
enum Result<T> {
case success(T)
case failure(String)
}
And something like this
class func login(username: String, password: String, completion: @escaping (Result<User>) -> Void){
//...
//let user = makeUserWithSomeData()
completion(Result.success(user))
}
And now you don't have to cast.
MyWebServices.login(username: username, password: password) {
(result) in
switch(result) {
case .success(let value):
useMyValue(user)
break
case .failure(let error):
print("Error: \(error)")
break;
}
}
By the way form Swift 3.1 lowerCamelCase for enums is preferred.
Upvotes: 3