Search code examples
iosswiftrx-swiftmoya

Updating Moya/RxSwift breaking my network calls


Updating my iOS app from Moya 8 to 11 and I have the following function in a network utility class which is called to get data from a server and map it for use in other classes:

func getServerData(endpoint: MyMoyaService) -> Observable<Any> {
    let provider = RxMoyaProvider<MyMoyaService>()
    return provider.request(endpoint)
        .filterSuccessfulStatusAndRedirectCodes()
        .mapJSON()
        .flatMap { response -> Observable<Any> in
            return Observable(…)
        }
}

With the updates, RxMoyaProvider was replaced with MoyaProvider and instead you're supposed to use .rx to use the RxSwift extensions. This now returns a Single instead of an Observable so in order to avoid compiler errors I also needed to insert asObservable()

func getServerData(endpoint: MyMoyaService) -> Observable<Any> {
    let provider = MoyaProvider<MyMoyaService>()
    return provider.rx.request(endpoint)
        .asObservable()
        .filterSuccessfulStatusAndRedirectCodes()
        .mapJSON()
        .flatMap { response -> Observable<Any> in
            return Observable(…)
        }
}

But the flatMap portion is not being called at all and my network calls don't work anymore. If I do this without RxSwift, just switching on the result, it works OK (but that doesn't fit with my current setup) so I know that the network call and the updates to the custom TargetType service are done correctly.

  1. How do I get this working again, (ideally without completely changing the entire setup, and
  2. (for extra credit) how do I take full advantage of the updated setup with Single instead of Observable (since I assume that by using asObservable I'm just missing out on useful features / cleaner code)

Solution

  • Seems the issue is retaining the MoyaProvider object… If I move the provider outside of the function and store it as a property in the class, then everything works properly.

    class MyClass {
         let provider = MoyaProvider<MyMoyaService>()
         func getServerData(endpoint: MyMoyaService) -> Observable<Any> {
            return provider.rx.request(endpoint)
               .asObservable()
               .filterSuccessfulStatusAndRedirectCodes()
               .mapJSON()
               .flatMap { response -> Observable<Any> in
                   return Observable(…)
               }
       }
    }
    

    From the providers documentation:

    Always remember to retain your providers, as they will get deallocated if you fail to do so.

    I suppose at some point they updated how these providers get deallocated?