swift 框架moya post请求遇到的坑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 框架moya post请求遇到的坑相关的知识,希望对你有一定的参考价值。

参考技术A 找了一大圈,发现国内根本没有解决的方法,去国外翻了一遍才找到,记录一下

1.用moya测试登陆post接口,发现传过去的没有包装成json,百度了好久,全是千篇一律的答案,stackoverflow上也没找到,无奈去github的issue上翻,总算找到附上地址 https://github.com/Moya/Moya/issues/1533 。然后总结下经历,之前以为是header的content-type设置的问题,发现moya4.0更新了一个新的header参数可以设置header了,貌似以前是用一种复杂的方法设置的,叫什么endxxx的,没仔细研究那个东西,反正用不上,用上的时候再说吧,然后把parameter参数放到了task中,其实刚开始的研究思路主要放在寻找moya中是否有一个属性能设置json传递, .requestCompositeParameters(bodyParameters: parameters, bodyEncoding: JSONEncoding.default, urlParameters: [:]),然后就是这句话,主要在于JSONEncoding吧,这个是task中返回的。然后如果想用以前的parameters的话,可以自己写一个,然后把parameters传递给bodyParameters就行了。

贴上解决方法

import Moya

let loginProvider = NetworkUtility.getMoyaProvider(LoginAPI.self)

public enum LoginAPI

    case loginUser([String: Any])

    case forgotPasswordOTP(String)

    case resetPassword([String: Any])



extension LoginAPI: TargetType

    public var baseURL: URL return URL(string: ConfigData.shared.getURL(forKey: DefaultsKeys.baseURL))!

    public var path: String

        switch self

        case .loginUser:

            return ConfigData.shared.getURL(forKey: DefaultsKeys.login)

        case .resetPassword:

            return ConfigData.shared.getURL(forKey: DefaultsKeys.resetPassword)

        case .forgotPasswordOTP:

            return ConfigData.shared.getURL(forKey: DefaultsKeys.forgotPasswordOTP)

       

   

    public var method: Moya.Method

        switch self

        case .loginUser:

            return .post

        case .resetPassword, .forgotPasswordOTP:

            return .put

       

   

    public var task: Task

        switch self

        case .loginUser(let bodyParameters),

              //UserLogin dictionaryRepresentation is used for this

             .resetPassword(let bodyParameters):

            return .requestCompositeParameters(bodyParameters: bodyParameters,

                                               bodyEncoding: JSONEncoding.default,

                                               urlParameters: [:])

        case .forgotPasswordOTP(let email):

            return .requestCompositeParameters(bodyParameters: [User.Keys.email: email],

                                               bodyEncoding: JSONEncoding.default,

                                               urlParameters: [:])

       

   

    public var headers: [String: String]?

        return NetworkUtility.getHeaders()

   

    public var sampleData: Data

        var data: Data! = nil

        switch self

        case .loginUser:

            data = NetworkUtility.loadJSON(jsonName: "3.33.4Success")

        case .resetPassword:

            data = NetworkUtility.loadJSON(jsonName: "ResetPassword")

        case .forgotPasswordOTP:

            data = NetworkUtility.loadJSON(jsonName: "VerifyUser")

       

        return data

   

使用 moya 和 alamofire 时使用参数编码发布请求错误

【中文标题】使用 moya 和 alamofire 时使用参数编码发布请求错误【英文标题】:Post request error with parameter encode when use moya and alamofire 【发布时间】:2017-08-03 11:16:00 【问题描述】:

我使用moya发出post请求,但是当我发送post时,服务器给我一个错误,它无法解码body参数。我使用URLEncoding.default来编码这样的参数

public var parameterEncoding: ParameterEncoding 
    return URLEncoding.default

会设置内容类型application/x-www-form-urlencoded,服务器接受的内容类型也一样

如果parameters是像"a":"b"这样的字典,那效果很好,但是如果字典包含数组或另一个字典,则服务器无法从请求体中获取参数。

前:


   "a":"xxx",
   "b":[
          "xxxxx",
          "xxxxx"
       ]

alamofire 会像这样编码 "a"="xxx"&b[]=xxxx&b[]=xxx

但服务器期望 a=xxx&b[0]=xxx&b[1]=xxxx

如何解决这个问题?

【问题讨论】:

【参考方案1】:

您可以手动构建参数字符串,然后将参数字符串链接到Url字符串。最后,只需通过 Alamofire 使用 url 发出请求,不带任何参数(它们已经在 url 中)。

参数串的构建方式:

    let dict = ["a":"xxx","b":["xxx","xxxxxxx"]] as [String : Any]
    var paramString = ""

    for key in dict.keys 
        let value = dict[key]
        if let stringValue = value as? String 
            paramString += "&\(key)=\(stringValue)"
        
        else if let arr = value as? Array<String> 
            for i in 0 ... arr.count - 1 
                paramString += "&\(key)[\(i)]=\(arr[i])"
            
        
        else
            //other type?
        
    

    if paramString.characters.count > 0 
        paramString = paramString.substring(from: paramString.index(paramString.startIndex, offsetBy: 1))
    

    print(paramString)
    //output is:  b[0]=xxx&b[1]=xxxxxxx&a=xxx

【讨论】:

感谢您的回答。我知道这可以解决这个问题。但我想在服务器界面上解决这个问题。我已经将服务器的内容类型更改为 Application/Json。

以上是关于swift 框架moya post请求遇到的坑的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Moya 框架重试请求

使用koa-body遇到的坑

Java RestTemplate post请求传递参数遇到的坑

做项目遇到的坑

python3编写脚本时遇到的坑......

2021-09-24 ruoyi框架中使用feign自定义服务,fegin使用遇到的坑