Reputation: 2557
I'm trying to implement some single solution for each callbacks in application. So I want any callback use the same class, or at least family of classes.
The common callbacks usage looks like this:
func foo(callback: ((success: Bool, result: Result?, error: Error?) -> Void)?) { }
Or:
func foo(success: ((result: Result) -> Void)?, failure: ((error: Error) -> Void)?) { }
I don't like any of them. I want to have single elegant solution for each callback. I found something similar in Alamofire library.
enum CallbackResult<T, V> {
case success(value: T?)
case failure(error: V?)
var isSuccess: Bool {
switch self {
case .success: return true
case .failure: return false
}
}
}
func foo(callback: ((result: CallbackResult<Any, AnyObject>) -> Void)?) {
callback?(result: .success(value: nil))
}
This solution it nice. But like in my example, not always we need to pass any value or error as a parameter. Anyway, compiler always need to know what type generic parameters should be of. So even if I don't meter what type value is, I always should put there at least Any
or AnyObject
. It is overcomplicated.
I've tried to change it with class solution:
class CallbackResult<T, V> {
let isSuccess: Bool
let value: T?
let error: V?
fileprivate init(success: Bool, value: T? = nil, error: V? = nil) {
self.isSuccess = success
self.value = value
self.error = error
}
static func success(value: T? = nil) -> CallbackResult {
return CallbackResult(success: true, value: value)
}
static func failure(error: V? = nil) -> CallbackResult {
return CallbackResult(success: false, error: error)
}
}
func foo(callback: ((result: CallbackResult<Any, AnyObject>) -> Void)?) {
callback?(result: CallbackResult.success(value: nil))
}
It has the same functionality. But even in this way it didn't solve my problem. You can't just write like this:
CallbackResult<_, Error>
It will not work.
Maybe somebody know solution to my problem? Some way to put default value maybe^ not to write Any
each time? Or for now there is only ugly way of using that approach?
Upvotes: 2
Views: 1055
Reputation: 351
Swift 3 added generic type aliases. These might help you avoid typing all types each time.
Example:
typealias AnyResult<E> = CallbackResult<Any, E>
typealias AnyCallback<E> = (AnyResult<E>) -> ()
func foo(callback: AnyCallback<String>?) {
callback?(.failure(error: "Ouch!"))
}
foo() { result in
if result.isSuccess {
// ...
}
}
Upvotes: 1