使用 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,那就太好了。

我的问题是,有什么方法可以使用 URLRequestConvertibleAlamofire 中将嵌套的 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)