Запрос RxSwift для каждой итерации массива

Я использую RxSwift для получения некоторых сетевых данных, и у меня возникают проблемы с выполнением запроса для каждой итерации массива. Это была моя идея:

  • У меня есть конечная точка API, которая возвращает массив объектов Objs, не содержащий данных о местоположении. Затем я перебирал массив Objs и для каждого получал данные о местоположении с идентификатором Obj. Что-то вроде этого:

(код упрощен)

var arrayObj = networkClient.request(getObjsEndpoint)
        .fetchObjLocationDetails(withNetworkClient: networkClient)
  • И fetchObjLocationDetails () будет примерно таким:

(код упрощен)

extension ObservableType where E == [Obj]? {
func fetchObjsLocationDetails(withNetworkClient networkClient: NetworkClient) -> Observable<[Obj]?> {
        return flatMap { Objs -> Observable<[Obj]?> in
            guard let unwrappedObjs = Objs as [Obj]? else { return Observable.just(nil) }

            let disposeBag = DisposeBag()
            var populatedObjs = [Obj]()

            unwrappedObjs.forEach { obj in
                let getLocationDetailsEndpoint = WeDriveParkAPI.getLocation(id: String(obj.id))

                networkClient.request(getLocationDetailsEndpoint)
                    .observeOn(MainScheduler.instance)
                    .subscribe(onNext: { json in
                        guard let populatedObj = Obj.fromJSON(json) as Obj? else { return }

                        populatedObjs += [populatedObj]
                        }, onError:{ e in

                    }).addDisposableTo(disposeBag)
            }
            return Observable.just(populatedObjs)
        }
    }
}

Это решение на самом деле не работает, потому что код даже не входит в закрытие подписки при следующем.

Имейте в виду, что я новичок в программировании Swift и RxSwift, так что будьте осторожны :) Любая помощь будет принята с благодарностью.


person Bruno Morgado    schedule 12.02.2016    source источник


Ответы (1)


Вместо того, чтобы делать настраиваемый оператор, вы можете использовать встроенный.

networkClient.request(getObjsEndpoint)
.map({ (objs:[Obj]?) -> [Obj] in
    if let objs = objs {
        return objs
    } else {
        throw NSError(domain: "Objs is nil", code: 1, userInfo: nil)
    }
})
.flatMap({ (objs:[Obj]) -> Observable<[Obj]> in
    return objs.toObservable().flatMap({ (obj:Obj) -> Observable<Obj> in
        let getLocationDetailsEndpoint = WeDriveParkAPI.getLocation(id: String(obj.id))
        return self.networkClient.request(getLocationDetailsEndpoint)
        .map({ (obj:Obj?) -> Obj in
            if let obj = obj {
                return obj
            } else {
                throw NSError(domain: "Obj is nil", code: 1, userInfo: nil)
            }
        })
    }).toArray()
})
.subscribeNext({ (objs:[Obj]) in
    print("Populated objects:")
    print(objs)
}).addDisposableTo(bag)
person Evgeny Sureev    schedule 13.02.2016