美文网首页Swift开发
Moya 请求链接拼接错误

Moya 请求链接拼接错误

作者: 092d567e5c1c | 来源:发表于2018-12-06 17:13 被阅读122次

    最近在写电商的功能,后台是 PHP 语言开发的。基于 Moya 强大的功能,不等 UI 做出图来我先把接口定义好,到时候直接调用,没想到事情没有想像的那么顺利。。。。

    第一个接口是登录,文档是这样的


    域名https://www.xxxx.com
    Path: /index.php?store_id=2&r=api/sso/login
    Method: POST
    Header

    参数名称 参数值 是否必须
    Content-Type application/x-www-form-urlencoded

    body

    参数名称 参数类型 是否必须
    username text
    nickname text
    avatar_url text

    很简单嘛,一通操作就写好了

    enum YKStoreApi {
       case login(username: String, nickname: String, avatar_url: String)
    }
    extension YKStoreApi: TargetType {
       var baseURL: URL {
           return URL(string: "https://www.xxxx.com")!
       }
       
       var path: String {
           switch self {
           case .login(_, _, _):
               return "/index.php?store_id=2&r=api/sso/login"
           }
       }
    
       var task: Task {
           switch self {
           case .login(let username, let nickname, let avatar_url):
               return .requestParameters(parameters: ["username": username, "nickname": nickname, "avatar_url": avatar_url], encoding: URLEncoding.httpBody)
           }
       }
    。。。。。。 无关紧要的就不贴了  。。。。。。
    }
    

    看着没啥毛病,来吧,没病走两步。请求结果是这样的

    Response: <NSHTTPURLResponse: 0x600003c22480> { URL: https://www.xxxx.com/index.php%3Fstore_id=2&r=api/sso/login } { Status Code: 404, Headers

    打印出的链接与想像中的好像不太一样,看看 Moya 源码是怎么拼接的吧

    public extension URL {
        /// Initialize URL from Moya's `TargetType`.
        init<T: TargetType>(target: T) {
            // When a TargetType's path is empty, URL.appendingPathComponent may introduce trailing /, which may not be wanted in some cases
            // See: https://github.com/Moya/Moya/pull/1053
            // And: https://github.com/Moya/Moya/issues/1049
            if target.path.isEmpty {
                self = target.baseURL
            } else {
                self = target.baseURL.appendingPathComponent(target.path)
            }
        }
    }
    
    验证是 appendingPathComponent() 方法拼接导致的错误

    这可怎么办,难道要修改源码吗?稍安勿躁,我大 Moya 如此牛逼应该不会有这么 low 的问题吧

    分析一下这个链接发现,它是同时拥有编码参数( body 里面的)url 参数(Path 中问号后面的部分)。查看 Moya 中 Task 类型发现有这样一个类型的任务,看注释的意思应该正是我需要的

    /// A requests body set with encoded parameters combined with url parameters.
        case requestCompositeParameters(bodyParameters: [String: Any], bodyEncoding: ParameterEncoding, urlParameters: [String: Any])
    

    大胆假设,小心验证。就按照这个思路修改一下原来的代码

    enum YKStoreApi {
       case login(username: String, nickname: String, avatar_url: String)
    }
    extension YKStoreApi: TargetType {
       var baseURL: URL {
           return URL(string: "https://www.xxxx.com")!
       }
       
       var path: String {
       switch self {
           case .login(_, _, _):
               return "/index.php"
           }
       }
    
       var task: Task {
           switch self {
           case .login(let username, let nickname, let avatar_url):
                return .requestCompositeParameters(bodyParameters: ["username": username, "nickname": nickname, "avatar_url": avatar_url], bodyEncoding: URLEncoding.httpBody, urlParameters: ["store_id": "2", "r": "api/sso/login"])
           }
       }
    。。。。。。 无关紧要的就不贴了  。。。。。。
    }
    

    改成这样之后重新请求一次,OK 成功了!

    Response: <NSHTTPURLResponse: 0x600003c22480> { URL: https://www.xxxx.com/index.php?store_id=2&r=api/sso/login } { Status Code: 200, Headers

    总结

    1. 平时 Moya 使用最多的 Task 类型是 requestParameters(parameters: [String: Any], encoding: ParameterEncoding),甚至不知道另外那个是干什么用的,但是人家的注释写的是一清二楚的。

    2.读开源项目的源码,要读精读通,不能似懂非懂。好的开源项目是最好的学习资料。

    相关文章

      网友评论

        本文标题:Moya 请求链接拼接错误

        本文链接:https://www.haomeiwen.com/subject/ereocqtx.html