New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use this with alamofireobjectmapper? #34
Comments
Below is simple example. import UIKit
import RxSwift
import RxAlamofire
import ObjectMapper
class Post: Mappable {
var id: Int = 0
var title: String = ""
required init?(_ map: Map) {
}
func mapping(map: Map) {
id <- map["id"]
title <- map["title"]
}
}
extension ObservableType {
public func mapObject<T: Mappable>(type: T.Type) -> Observable<T> {
return flatMap { data -> Observable<T> in
let json = data as? AnyObject
guard let object = Mapper<T>().map(json) else {
throw NSError(
domain: "",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "ObjectMapper can't mapping"]
)
}
return Observable.just(object)
}
}
public func mapArray<T: Mappable>(type: T.Type) -> Observable<[T]> {
return flatMap { data -> Observable<[T]> in
let json = data as? AnyObject
guard let objects = Mapper<T>().mapArray(json) else {
throw NSError(
domain: "",
code: -1,
userInfo: [NSLocalizedDescriptionKey: "ObjectMapper can't mapping"]
)
}
return Observable.just(objects)
}
}
}
class ViewController: UIViewController {
var disposeBag: DisposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
JSON(.GET, "http://jsonplaceholder.typicode.com/posts").mapArray(Post.self).subscribeNext { (posts) in
for post in posts {
print(post.title)
}
}.addDisposableTo(disposeBag)
}
} |
@kciter Thanks. But what if I need to do nested alamofire requests? Do I make both request an observable? or just one observable with nested alamofire? |
@rlam3 What do you think is below to use? Observable.just()
.flatMap {
return JSON(.GET, "http://jsonplaceholder.typicode.com/posts").mapArray(Post.self)
}
.flatMap { posts in
return JSON(.GET, "http://jsonplaceholder.typicode.com/comments").mapArray(Comment.self).map { comments in
return (posts, comments)
}
}
.subscribeNext { result in
// ...
}.addDisposableTo(disposeBag) |
@kciter From what it looks like, you're mapping the comments to the post themselves correct? How do I get the values out of result? result.post? result.comment? Say for example. I need to asynchronously obtain a JSON web token and use this token in the next request like retrieving a post. Is there a way similar to promisekit in rxswift for this? Like getjsonwebtoken().then{
jwt in
getPosts(jwt:jwt){
posts in
// update ui with posts
}
} |
Found http://www.finneycanhelp.com/tag/rxswift/ ... I guess what was returned for result should be more like (posts, comments) and from there we can do what we need |
getjsonwebtoken().
.flatMap { jwt in
return getPosts(jwt: jwt).mapArray(Post.self) // mapArray is ObservableType extension.
}
.subscribeNext { posts in
// update ui...
}.addDisposableTo(disposeBag) |
@kciter When I use flatMap to chain the second time. It gave me the following error:
What does this mean and how should I resolve this? Thanks! |
@rlam3 Please show me your code. :) |
@kciter Looks like I was able to get it to work now. I believe it was a mapping issue. Thanks! My next problem is that Swift doesn't recognize my JSON parameters? Is there a specific way to implement headers and parameters when using Alamofire.JSON this way? Everything is installed correctly. When I cmd + left-click on "JSON", it does not take me to the function. It returns back to me a question mark. Whereas the second one does take me to the function. // This Doesnt work like this
Observable.just()
.flatMap{
let csrf: String = api.getCSRFTokenFromAPI()
return JSON(.POST,"http://localhost:5000/api/auth", parameters: ["username": "XXXX@gmail.com", "password": "XXXX"], encoding: .JSON, headers: ["X-CSRFToken" : csrf])
.subscribeNext{
(auth_token) in
print("Auth TOKEN !! \(auth_token)")
}.addDisposableTo(disposeBag) <<<<< ERROR HERE
// Cannot invoke 'addDisposableTo' with an argument list of type '(DisposeBag)'
// This works down here
Observable.just()
.flatMap{
return JSON(.GET,"http://localhost:5000/api/v1/csrf_token")
}.subscribeNext{
csrf_token in
print("CSRF TOKEN !! \(csrf_token)")
}.addDisposableTo(disposeBag) Really new to RxSwift haha. |
URL Strings are great and all. But I'd like to get more control over my requests that I build when I am doing "Alamofire.request" instead of RxAlamofire.request because I'm trying to update the body of my json POST. Is there a way around this? This seems much more complicated than it should be since all I'm trying to do is obtain a token and then use that token in the next request. I'm observing a patter that Observables run on different sessions and don't conincide when I use the Alamofire.request way so I'm using a using a Manager.sharedInstance way now to test if the cookies/session is in the same. But I'm running into the following print statement error where it says ERROR: "Ambiguous reference to member 'print(_:seperator:terminator)'" let manager = APIClient().sharedInstance
// GET JWT
Observable.just()
.flatMap{
// CSRF
return manager
.rx_responseJSON(.GET, "http://localhost:5000/api/v1/csrf_token", parameters: nil, encoding: .JSON, headers: nil)
}
.flatMap{
(r,d) in
let csrf = d["csrf_token"]
// JWT
return manager.rx_responseJSON(.POST,"http://localhost:5000/api/auth", parameters: ["username": "XXXX@gmail.com", "password": "XXXX"], encoding: ParameterEncoding.JSON, headers: ["X-CSRFToken" : csrf, "Content-Type": "application/json"]).map{
(response) in
return response
}
}
.subscribeNext{
(response) in
print(response) <<<<<< ERROR HERE, not sure how to debug this.
}.addDisposableTo(disposeBag) <<<< Generic element error But If I remove print statement. it will tell me: ERROR: "Generic parameter 'Element' could not be inferred" |
Hello, @rlam3 Observable.just()
.flatMap{
return JSON(.GET, "http://localhost:5000/api/v1/csrf_token", parameters: nil, encoding: .JSON, headers: nil)
}
.map { response in
let csrf = response["csrf_token"] as! String
return JSON(.POST, "http://localhost:5000/api/auth", parameters: ["username": "XXXX@gmail.com", "password": "XXXX"], encoding: .JSON, headers: ["X-CSRFToken" : csrf, "Content-Type": "application/json"])
}
.subscribeNext{ response in
print(response)
}.addDisposableTo(disposeBag) The biggest difference is changed |
@kciter Okay. I tried your following code but my response only give me back the following:: <FlatMap<Request, Observable<AnyObject>>: 0x7fbc1b647990> when it prints out and it doesn't have any properties or attributes I can call onto from the observable. How do I interact with the second JSON response? Thanks! |
@rlam3 |
@kciter i see... also I'd like to mention that print statements inside of "flatMap{}" usually triggers // Ambiguous reference to member 'print' Any reason why this may happen or why it is not a good idea to put a print statement inside flatMap before the return statement? |
@kciter I am trying to use the example you provided in the second comment to this issue with latest versions of Swift, ObjectMapper and RxAlamofire and it fails during "map(json)". Could you please provide an updated example? |
I have resolved the issue i was having by changing the
to
|
How to use this with alamofireobjectmapper?
Please provide short example
I'm trying to nest several alamofire requests. Is it possible that you provide an example with the documentation? Thanks!
The text was updated successfully, but these errors were encountered: