Reputation: 481
I'm trying to write an API layer using RxSwift and RxAlamofire. Here is the code for API request.
public func _request(_ method: Alamofire.HTTPMethod, url: URLConvertible, parameters: [String : Any]? , encoding: ParameterEncoding, headers: [String : String]?, isSecondTryAfterAuth: Bool = false) -> RxSwift.Observable<(HTTPURLResponse, Any)>
{
return RxAlamofire
.requestJSON(method, url, parameters: parameters, encoding: JSONEncoding.default, headers: self.appDelegateInstance.refreshToken)
.map({ (response, json) -> Observable<(HTTPURLResponse, Any)> in
return Observable.just(response, json)
})
}
I got an error in .map function "Closure tuple parameter '(HTTPURLResponse, Any)' does not support destructuring". Any idea about how to solve this?
Upvotes: 1
Views: 1443
Reputation: 21144
You are using map method, which has the following method signature.
/**
Projects each element of an observable sequence into a new form.
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
- parameter transform: A transform function to apply to each source element.
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
public func map<R>(_ transform: @escaping (Self.E) throws -> R) -> RxSwift.Observable<R>
As you can see, the transform closure is only supposed to change the elements to the type you want your Observable to be. In your case however, it seems like you are trying to return an Obsevable
of <(HTTPURLResponse, Any)>
ie. Observable<(HTTPURLResponse, Any)>
as it can be seen from _request
method signature but instead you return Observable<Observable<(HTTPURLResponse, Any)>>
and that is why you get the error.
Look at this simple example,
let b = Observable.of(1, 2, 3, 4, 5).map { "\($0 + 1)" }
The example transforms element and adds 1 to each element and returns it as string.. Here, you are transforming each element.
The type of b
at this point is Observable<String>
In your above example, you change it in such a way that you are returning observable from map again.
Your code can be visualized like this,
let b = Observable.of(1, 2, 3, 4, 5).map { Observable.just("\($0 + 1)) }
Now, b
is not Observable<String>
instead it is Observable<Observable<String>>
.
This is exactly the problem that you have with your code.
This is your _request
method,
public func _request(_ method: Alamofire.HTTPMethod, url: URLConvertible, parameters: [String : Any]? , encoding: ParameterEncoding, headers: [String : String]?, isSecondTryAfterAuth: Bool = false) -> RxSwift.Observable<(HTTPURLResponse, Any)>
The expected return type is rather Observable<(HTTPURLResponse, Any)>
But you do some magic and return,
Observable<Observable<(HTTPURLResponse, Any)>>
Based on the return type of your method, I am hoping this is what you were trying to do,
return RxAlamofire
.requestJSON(method, url,
parameters: parameters,
encoding: JSONEncoding.default,
headers: self.appDelegateInstance.refreshToken)
.map( { (response, json) -> (HTTPURLResponse, Any) in
return (response, json)
})
By the way, the map at the end looks redundant, since it is simply returning the input, unless you plan to transform the input type (response, json)
to some other type.
Upvotes: 3
Reputation: 270980
The closure apparently has only one parameter that is a tuple of two values (HTTPURLResponse
and Any
), yet the way you wrote (response, json)
tells swift that you are trying to deconstruct the single tuple parameter into 2 parameters, which is not allowed.
You have to write it as one parameter:
.map({ tuple -> Observable<(HTTPURLResponse, Any)> in
return Observable.just(tuple)
})
You can also write it like this if the types can be inferred:
.map { Observable.just($0) }
Upvotes: 1