How to return an Observable sequence with optional value

57 views Asked by At

enter image description here

class Api{
    
    static let shared = Api()
    private let provider = MoyaProvider<MultiTarget>(plugins:[NetworkLoggerPlugin(),CryptoPlugin()])
    
    public func send<T : Codable>(_ target : TargetType, type : T.Type) -> Observable<T?> {
        let mTarget = MultiTarget(target)
        return provider.rx.request(mTarget)
            .asObservable()
            .filterSuccessfulStatusCodes()
            .map { result in
                print(String(data: result.data, encoding: .utf8) ?? "111")
                
                let responseModel = try JSONDecoder().decode(ResponseModel<T>.self, from: result.data)
                if(responseModel.code != 0) { // business error
                    let msg = (responseModel.msgCode != nil) ? Localized(key: "\(responseModel.msgCode!)") : responseModel.msg
                    UIApplication.shared.currentKeyWindow()?.showHUD(msg)
                    return nil
                }
                if(responseModel.data == nil){
                    responseModel.data = T.Type()
                }
                return responseModel.data
            }
            .catchAndReturn(T.self as? T)
    }
}

the problem is sometimes the server side will return nil data EVEN there is no http error and business error. In this case, I want to return an empty instance to the subscriber. that's why I have this code : responseModel.data = T.Type()

but as you can see, there is a compile error, I don't know what's happening.

Appreciate for any suggestion:)

1

There are 1 answers

2
Daniel T. On

Just remove the offending line. You already established that sometimes the server can return nil so allow this function to return nil...

.map { result in
    print(String(data: result.data, encoding: .utf8) ?? "111")

    let responseModel = try JSONDecoder().decode(ResponseModel<T>.self, from: result.data)
    if responseModel.code != 0 { // business error
        let msg = (responseModel.msgCode != nil) ? Localized(key: "\(responseModel.msgCode!)") : responseModel.msg
        UIApplication.shared.currentKeyWindow()?.showHUD(msg)
        return nil
    }
    return responseModel.data
}

If you really want to be able to detect an error at the call sight, then have this function emit an error.