Home > Software design >  Swift 5: Return a tuple in observable with RxSwift
Swift 5: Return a tuple in observable with RxSwift

Time:03-10

I want to return a tuple using an observable but I get this error in the last return line : " Cannot convert return expression of type '(PublishSubject, Bool)' to return type 'Observable<(MessageStatus, Bool)>' " struct MessageStatus { let message: String let code: Int }

class ServiceNetwork: Service {
    
    func getStatus() -> Observable<(MessageStatus, Bool)>{
        
        let query = Bundle.main.query ?? ""
        let responseMessage =  PublishSubject<MessageStatus>()
        let isSuccess = PublishSubject<Bool>()
                
        let body = ["query": "\(query)"]
        
        _ = response(body: body)
            
            .map { try JSONDecoder().decode(Data.self, from: $0) }
        
            .subscribe(onNext: { response in
                guard response.data != nil else {
                    let error = response.errors?.data?.first
                    let failure = MessageStatus(message: error.message , code: error.code)
                    responseMessage.onNext(failure)
                    isSuccess.onNext(false)
                    return
                }
                let sucess = MessageStatus(message: "Success", code: 200)
                responseMessage.onNext(success)
                isSuccess.onNext(true)
                
            }) return (responseMessage, isSuccess) // error here
    }
}

CodePudding user response:

Just swap the subscribe out for a map. Something like the below:

func getStatus() -> Observable<(MessageStatus, Bool)> {
    let query = Bundle.main.query ?? ""
    let body = ["query": "\(query)"]
    
    return response(body: body)
        .map { try JSONDecoder().decode(Data.self, from: $0) }
        .map { response in
            guard response.data != nil else {
                let error = response.errors?.data?.first
                let failure = MessageStatus(message: error.message , code: error.code)
                return (failure, false)
            }
            let success = MessageStatus(message: "Success", code: 200)
            return (success, true)
        }
}

CodePudding user response:

You have to return Observable stream. Can do it like in below example.

class ServiceNetwork: Service {
    
    func getStatus() -> Observable<(MessageStatus, Bool)>{
        Observable.create { subscriber in
            let query = Bundle.main.query ?? ""                    
            let body = ["query": "\(query)"]
        
            let disposable = response(body: body)
            
                .map { try JSONDecoder().decode(Data.self, from: $0) }
        
                .subscribe(onNext: { response in
                    guard response.data != nil else {
                        let error = response.errors?.data?.first
                        let failure = MessageStatus(message: error.message , code: error.code)

                        subscriber.onNext((failure, false))
                        return
                    }
                    let success = MessageStatus(message: "Success", code: 200)
                    subscriber.onNext((success, true))
                
                })
             
            return Disposables.create {
                disposable.dispose()                
            }
        }
    }
}

Little advice, think about error handling outside of this function. And, additional, handle onError case.

  • Related