Как использовать нумерацию страниц с использованием RxSwift и Alamofire? - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь потреблять API с alamofire и rxswift. Я написал методы, но onNext наблюдателя вызывается только один раз. Я пытаюсь сделать это с помощью рекурсивного вызова. Что не так с этим? Api будет возвращать 10 объектов за раз, основываясь на отметке времени. Поэтому я проверяю, содержит ли только что возвращенный массив 10 объектов. Если да, то есть больше, если нет, то это конец.

func fetchPersonalization(fromList:[Personalization],timeStamp:Int) -> Observable<PersonalizationContainer>
    {


        let dictHeader = ["Accept":"application/json","regid" :  pushtoken , "os" : "ios" , "token" : token , "App-Version" : "1324" ,  "Content-Type" :  "application/json"]

        return fetchPersonalizationUtil(dictHeader: dictHeader, timeStamp: timeStamp)
            .flatMap { (perList) -> Observable<PersonalizationContainer> in

                    let persoList:[Personalization] = perList.list
                    let finalList = fromList + persoList
                    if(persoList.count==10){
                        let newTimeStamp = persoList.last!.lastModifiedAt! - 1

                        return Observable.merge(Observable.just(PersonalizationContainer(l: finalList, d: perList.data)),
                            self.fetchPersonalization(fromList:finalList,timeStamp: newTimeStamp)
                        )
                            //self.fetchPersonalization(fromList:finalList,timeStamp: newTimeStamp)



                    }else {
                        return Observable.just(PersonalizationContainer(l: finalList, d: Data()))
                    }

        }
    }

    func fetchPersonalizationUtil(dictHeader:[String:String],timeStamp:Int) -> Observable<PersonalizationContainer>
    {

        return Observable<PersonalizationContainer>.create({ (observer) -> Disposable in
            Alamofire.request("https://mranuran.com/api/hubs/personalization/laterthan/\(timeStamp)/limit/10/" ,headers: dictHeader).responseData { response in
                if let json = response.result.value {
                    //print("HUBs JSON: \(json)")

                    do {
                        let list = try JSONDecoder().decode([Personalization].self, from: json)
                        let pContainer = PersonalizationContainer(l: list, d: json)
                        print("ANURAN \(list[0].name)")
                        observer.onNext(pContainer)
                        observer.onCompleted()
                    }catch {
                        print(error)
                        observer.onError(error)
                    }

                }
                else{
                    observer.onError(response.result.error!)
                }
            }

            return Disposables.create()
        })

    }

Я поставил точку останова на методе onNext, и казалось, что он вызывается только один раз. Застряв в этом в течение нескольких часов и примера RxSwift GithubRepo в их официальном репозитории github, я не могу понять, что они делают. Что может быть не так с моим процессом?

1 Ответ

0 голосов
/ 03 сентября 2018

Я написал это некоторое время назад, используя Promises, здесь он использует Singles.

Вы передаете:

  1. семя, которое используется для первого сетевого вызова.
  2. pred, который получит результаты самого последнего вызова и выдаст либо аргумент для следующего сетевого вызова, либо nil, если он будет выполнен. (Здесь вы можете проверить счетчик и вернуть метку следующего времени, если потребуется другой вызов.)
  3. производитель, который совершает сетевой вызов.

В конце концов он возвращает Single с массивом всех результатов. Произойдет ошибка, если какая-либо внутренняя сеть вызовет ошибку.

func accumulateWhile<T, U>(seed: U, pred: @escaping (T) -> U?, producer: @escaping (U) -> Single<T>) -> Single<[T]> {
    return Single.create { observer in
        var disposable = CompositeDisposable()
        var accumulator: [T] = []
        let lock = NSRecursiveLock()
        func loop(_ u: U) {
            let product = producer(u)
            let subDisposable = product.subscribe { event in
                lock.lock(); defer { lock.unlock() }
                switch event {
                case let .success(value):
                    accumulator += [value]
                    if let u = pred(value) {
                        loop(u)
                    }
                    else {
                        observer(.success(accumulator))
                    }
                case let .error(error):
                    observer(.error(error))
                }
            }
            _ = disposable.insert(subDisposable)
        }
        loop(seed)
        return disposable
    }
}

Я не думаю, что блокировка действительно необходима, но я вставил ее на всякий случай.

...