GoldenJoe
GoldenJoe

Reputation: 8002

Any way to let an enum hold a generic object and access it later without typecasting?

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

Answers (1)

Bilal
Bilal

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

Related Questions