Skip to content

Instantly share code, notes, and snippets.

@amlcurran
Last active May 21, 2018 08:56
Show Gist options
  • Save amlcurran/5a09332a835a2dfdce146de9babc9f74 to your computer and use it in GitHub Desktop.
Save amlcurran/5a09332a835a2dfdce146de9babc9f74 to your computer and use it in GitHub Desktop.
Better completion blocks by using higher order functions
func completion<Result>(onResult: @escaping (Result) -> Void, onError: @escaping (Error) -> Void) -> ((Result?, Error?) -> Void) {
return { (maybeResult, maybeError) in
if let result = maybeResult {
onResult(result)
} else if let error = maybeError {
onError(error)
} else {
onError(SplitError.NoResultFound)
}
}
}
// Use where a completion block will give a `Bool` value indicating it was successful or not.
func completion(onSuccess: @escaping () -> Void, onFailure: @escaping () -> Void) -> ((Bool) -> Void) {
return { success in
if (success) {
onSuccess()
} else {
onFailure()
}
}
}
enum SplitError: Error {
case NoResultFound
}
@Monserg
Copy link

Monserg commented May 21, 2018

Hi, I'm try to refactoring my own completion like this:
public func executeGET(byMethodAPIType methodAPIType: MethodAPIType, completion: @escaping (ResponseAPIType?) -> Void) {
...
}
How can I modify my completion block with your func completion()?
Thanks.

@amlcurran
Copy link
Author

@Monserg

I'm assuming that if you get no ResponseAPIType back then that is an error? In that case, you could refactor like this:

public func executeGET(byMethodAPIType methodAPIType: MethodAPIType, onComplete: @escaping (ResponseAPIType) -> Void, onError: @escaping () -> Void) {
  let response = // do the work here
  if let response = response {
    onComplete(response)
  } else {
    onError()
  }
}

However, if you can get a ResponseAPIType which contains an error then you will have to refactor a little differently.

Hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment