intsig171 / SmartCodable

SmartCodable is a data parsing library based on Codable. It is simple to use, with robust compatibility being one of its main features. SmartCodable 是基于Codable实现的数据解析库。简单易用,强悍的兼容性是SmartCodable的主要特点。 表层API和功能几乎和HandyJSON一致,支持快速的迁移。
https://smart-codable.vercel.app
MIT License
417 stars 43 forks source link

关于使用方法请教 #44

Closed biqinglin closed 2 months ago

biqinglin commented 2 months ago
class NFRequestResponse<T: SmartCodable>: SmartCodable {
    var code: Int?
    var msg: String?
    var body: T?
    required init() {}
}

现在我有这样一个结构体,其中body可能是nil、string、key-value、array,我用moya框架构造请求:

static func NFRequestModule<T: SmartCodable>(path: String, method: Moya.Method = .get, param: [String: Any]?, done: @escaping ((_ succeed: Bool, _ data: T?) -> Void)) {
        let api = NFAPI()
        api.requestPath = path
        api.requestParam = param
        api.requestMethod = method
        // 设置超时
        let timeoutClosure = { (endpoint: Endpoint, done: @escaping MoyaProvider<NFAPI>.RequestResultClosure) in
            do {
                var request = try endpoint.urlRequest()
                request.timeoutInterval = api.timeoutInterval
                done(.success(request))
            } catch {
                return
            }
        }
        let provider = MoyaProvider<NFAPI>(requestClosure: timeoutClosure)
        provider.request(api) { result in
            // 处理结果
            self.handleResult(result: result, done:done)
        }
    }

    private static func handleResult<T: SmartCodable>(result:Result<Moya.Response, MoyaError>, done: @escaping ((_ succeed: Bool, _ data: T?) -> Void)){
        switch result {
        case .success(let response):
            let dic = try? response.mapJSON() as? Dictionary<String, Any>
            let result = NFRequestResponse<T>.deserialize(from: dic)
            // 过滤状态码
            let code = result?.code ?? -999
            switch code {
            case 0:
                done(true, result?.body)
                break
            case -1:
                // 服务器异常
                done(false, nil)
                break
            case 100101:
                // 当前版本过低,请更新软件版本
                done(false, nil)
                break
            default:
                // 未知错误
                done(false, nil)
                break
            }
            // 方便调试,打印请求信息
            if let request = response.request,
                let method = request.method,
                let json = String(data: response.data, encoding: .utf8){
                debugPrint("~~~~~~~~~~~Request Start~~~~~~~~~~~~")
                debugPrint("Method:\(method.rawValue)\nURL:\(request)\nBody:\(String(describing: request.httpBody))\nResult:\n\(json)")
                debugPrint("~~~~~~~~~~~Request End~~~~~~~~~~~~")
            }
        case .failure(let error):
            // 网络错误
            debugPrint(error)
            done(false, nil)
        }
 }

我的问题是,如果现在body是个string,我应该怎么在外层定义data类型,传参去发起请求,这个data就是一个string,这里小白不太懂想咨询一下

extension NFRequestManager {
    /// 请求图形验证码
    static func getCodeImage(param: [String: Any]?, done: @escaping (_ succeed: Bool ,_ data: NFSingleStringModel?) -> Void) {
        NFRequestModule(path: NFNetworkPath.getCodeImage.rawValue, method: .post, param: param, done: done)
    }
}

class NFSingleStringModel: SmartCodable {
    var body: String?

    required init() {}
}

我这样写不对

biqinglin commented 2 months ago

我试出来了,感谢大佬提供,希望可以一直完善哦,我是从handyJson过来的

extension String: SmartCodable { }
intsig171 commented 2 months ago

虽然这样做可以的,但不太建议这样做。 基础数据类型最好不要遵循SmartCodable。 如果方便的话,提供一个可以运行的demo,我了解一下你的需求。 可以加一下QQ群: 865036731

biqinglin commented 2 months ago

demo要含内网地址才能运行,我描述一下吧,服务器返回的结构体是:

var code: Int?
var msg: String?
var body: T?

这里面body的类型不确定,可能是nil、string、dic、array,都有可能,那我在发起请求,构造response data的时候,要遵循SmartCodable,如果是dic这种就很明确,比如:

struct Body: SmartCodable {
    var count: Int
    var list: []
}

但是当body是nil、string的时候,我不知道怎么定义这个结构体

intsig171 commented 2 months ago

如果body中有多种数据类型的情况,可以使用SmartAny。 image

intsig171 commented 2 months ago

你也可以自己接管解析。 image image

biqinglin commented 2 months ago

感谢回复~祝生活愉快