使用 URLRequestConvertible 协议将 JSON 嵌套为请求参数 (Alamofire)
Posted
技术标签:
【中文标题】使用 URLRequestConvertible 协议将 JSON 嵌套为请求参数 (Alamofire)【英文标题】:Nested JSON as Request parameters with URLRequestConvertible protocol (Alamofire) 【发布时间】:2017-04-20 07:46:48 【问题描述】:Alamofire 提供了一个非常方便的协议 URLRequestConvertible,通过它我可以通过创建路由器类以更托管的方式管理我的 REST api。
一切正常,直到我不得不使用 Post 方法 请求 REST api,我必须将嵌套的 JSON 作为参数 传递如下:-
“studentID” : "297",
“studentName” : “Jack”,
“FilterValues” : [
“Field1” : “code”,
“Field2” : “1234232”,
“Field3” : “111”
]
我面临的问题是,当我使用基本 JSON 参数进行 Rest 调用时,协议工作正常,如下所示:-
“field1” : "jack",
“field2” : “1233434”,
"field3" : "test"
但当我不得不使用嵌套 JSON 进行调用时,二级 JSON 被忽略,并将上述参数处理如下:
“studentID” : "297",
“studentName” : “Jack”,
“FilterValues” : [
]
这是我的路由器类:-
class Router: URLRequestConvertible
static let baseURL = "http://xxxxxx.com"
case login (username: String, password: String)
case studentList (studentID: String, studentName:String)
var method: HTTPMethod
return .post
var path: String
switch self
case .login:
return "/login"
case .studentList:
return "/list"
public func asURLRequest() throws -> URLRequest
let parameters: [String: Any] =
switch self
case .login(let username, let password):
return ["username": username, "password": password]
case .studentList (let studentID, let studentName):
return ["studentID": studentID, "studentName": studentName, "FilterValuess": [["Field1": "code", "Field2": "someValue", "Field3": "someValue"]]]
default:
return [:]
()
let url = try Router.baseURL.asURL()
var request = URLRequest(url: url.appendingPathComponent(path))
request.httpMethod = method.rawValue
request.setValue("application/json", forHTTPHeaderField: "Accept")
// request.setValue("application/json", forHTTPHeaderField: "Content-Type") Tried no success
// request.httpBody = try! JSONSerialization.data(withJSONObject: parameters) Tried With JSONSerialization but no success.
return try URLEncoding.default.encode(request, with: parameters as! Parameters)
登录 API 工作正常。但是 studentList 没有成功,因为 Alamofire 不识别 JSON 参数。
通过谷歌搜索了一整天的解决方案,但找不到。 然后我尝试使用 Alamofire 另一个请求 api,如下所示:-
let parameters = ["studentID": studentID, "studentName": studentName, "FilterValuess": [["Field1": "code", "Field2": "someValue", "Field3": "someValue"]]] as [String: Any]
var request = URLRequest(url: URL(string: "http://xxxxxx.com/list")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters)
Alamofire.request(request)
.responseString(completionHandler: response in
switch response.result
case .failure(let error):
print(error)
if let data = response.data, let responseString = String(data: data, encoding: .utf8)
print(responseString)
case .success(let responseObject):
// Received desired output
print(responseObject)
)
这提供了所需的输出。但我想通过 URLRequestConvertible 实现结果,因为我不想以不同的方式处理每个 api。如果我作为 URLRequestConvertible 子类的 Router 类能够处理我所有的 REST api,那就太好了。
我的问题是,有什么方法可以使用 URLRequestConvertible 在 Alamofire 中将嵌套的 JSON 作为参数发送?
任何帮助都非常值得赞赏。
【问题讨论】:
【参考方案1】:修改最后一行
return try URLEncoding.default.encode(request, with: parameters as! Parameters)
到
return try JSONEncoding.default.encode(request, with: parameters)
【讨论】:
以上是关于使用 URLRequestConvertible 协议将 JSON 嵌套为请求参数 (Alamofire)的主要内容,如果未能解决你的问题,请参考以下文章
使用 URLRequestConvertible 的单元测试中的链接错误
如何减少 responseJSON 中的样板,就像我使用 URLRequestConvertible 对相关的 Web 调用进行分组一样
类型不符合 Alamofire 的协议“URLRequestConvertible”
Swift 3 - 创建简单请求方法 POST (URLRequestConvertible) 的问题
从 URLRequestConvertible 扩展时设置多部分请求的最佳方法是啥
无法将“NSMutableURLRequest”(0x11beb7040)类型的值转换为“Alamofire.URLRequestConvertible”(0x11beb9040)