screenMonkey MonkeyMan
screenMonkey MonkeyMan

Reputation: 423

How do I use RxSwift with AlamoFire and SwiftyJSON?

I'm trying to learn RxSwift and currently I'm trying to use it in relation to AlamoFire and SwiftyJSON, that is, to observe when JSON has been downloaded so that I can parse it. I have working code for getting JSON:

guard let myURL = URL(string: "https://api.myjson.com/bins/e5gjk") else { return }

var myArray = [People]()
let myObserver = Observable.from(myArray)

Alamofire.request(myURL, method: .get)
    .validate()
    .responseJSON{ response in
        guard response.result.isSuccess else {
            print("Error")
            return
        }

        let json = JSON(response.result.value)

        for i in 0...json["employees"].count {
            let people = People()
            people.name = json["employees"][i]["firstName"].stringValue
            people.job = json["employees"][i]["job"].stringValue

            myArray.append(people)
        }

        for i in myArray {
            print(i.name)
            print(i.job)
        }
}

myObserver.subscribe(onNext: {
    print($0)
}, onError: { error in
    print(error)
}, onCompleted: {
    print("completed")
}, onDisposed: {
    print("disposed")
}).disposed(by: DisposeBag())

As you can see, I have parsed the JSON as well. I guess that the point of RX here would be to use the data in onNext once it has been parsed, correct? Or have I misunderstood its purpose?

Anyway, I have an observer on myArray: let myObserver = Observable.from(myArray). In my head, subscribe onNext should be triggered as soon as myArray gets data, but that's not happening. What happens is that completed is run immediately, then the JSON networking and parsing takes place. The subscription is not triggered when myArray gets new data. Have I missed something or misunderstood RX's purpose?

EDIT Or wait, should the whole JSON handling and parsing be in the onNext?

Upvotes: 0

Views: 2809

Answers (1)

you need to create your observer. This should work :

        let observer = Observable<People>.create { (observer) -> Disposable in
            Alamofire.request(myURL, method: .get)
            .validate()
            .responseJSON { response in
                guard response.result.isSuccess else {
                    print("Error")
                    observer.on(.error(response.result.error!))
                    return
                }
                let json = JSON(response.result.value)

                for i in 0...json["employees"].count {
                    let people = People()
                    people.name = json["employees"][i]["firstName"].stringValue
                    people.job = json["employees"][i]["job"].stringValue

                    observer.on(.next(people))
                    myArray.append(people)
                }

                observer.on(.completed)

                for i in myArray {
                    print(i.name)
                    print(i.job)
                }
           }
           return Disposables.create()
        }

then you can subscribe to your observer of type Observable<People>

    observer.subscribe { (event) in
        switch event {
        case .next(let people):
            print(people.job)
            print(people.name)
        case .error(let error):
            print("error \(error.localizedDescription)")
        case .completed:
            print("completed")
        }
    }.disposed(by: disposeBag)

Upvotes: 1

Related Questions