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请求遇到的坑的主要内容,如果未能解决你的问题,请参考以下文章