'Swift 5: Return a tuple in observable with RxSwift

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
    }
}


Solution 1:[1]

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)
        }
}

Solution 2:[2]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Multix