Reputation: 854
Assuming we have the following method:
func searchLocation(keyword: String, completion: @escaping RequestResult<[Location])>)
where RequestResult
is a typealias to public typealias RequestResult<T> = (Result<T>) -> ()
and another method:
func throttleRequest<T>(request: PLACEHOLDER, completion: @escaping RequestResult<[T]> {
request { result in
print("Capturing some data") // do some stuff with the result in this scope
completion(result) // tell the caller the network function finsihed with `result`
}
}
How should I modify the method signatures so I can do something like this:
throttleRequest(request: {
searchLocation(keyword: "New York", completion: PLACEHOLDER)
},
completion: { result in
if case .success(let found) = result {
print("location found")
}
})
so that the following gets printed:
$ Location found
$ Capturing some data
I've entered PLACEHOLDER above on some type definitions, since I can't really figure out what's proper.
Upvotes: 0
Views: 39
Reputation: 23485
First, let's use a proper return type instead of ()
which is the same as Void
. It's easier to read when you explicitly specify you're returning void instead of writing ()
. In any case, what you want is a lambda function parameter.
IE: You want a function that takes a lambda as an argument. Therefore:
public typealias RequestResult<T> = (Result<T, Error>) -> Void
func searchLocation(keyword: String, completion: RequestResult<[Location]>) {
completion(.success([Location()]))
}
func throttleRequest<T>(request: (RequestResult<[T]>) -> Void, completion: @escaping RequestResult<[T]>) {
request {
print("Capturing some data")
completion($0)
}
}
So the syntax for a function/lambda as a parameter is: (ArgumentType...) -> ReturnType
(Int) -> Void
is a function that takes an int, returns Void/nothing.(T) -> U
is a function that takes a T argument and returns a U.Likewise, if you want the parameter to be optional, then it is defined as:
((Arguments...) -> ReturnType)?
Usages:
throttleRequest(request: { result in
self.searchLocation(keyword: "New York", completion: result)
}, completion: { result in
switch result {
case .success(let locations):
print(locations)
case .failure(let error):
print(error)
}
})
Or easier to read (imo you make _ request
the parameter):
throttleRequest({ self.searchLocation(keyword: "New York", completion: $0) }) {
switch $0 {
case .success(let locations):
print(locations)
case .failure(let error):
print(error)
}
}
Upvotes: 0