Alamofire:发送带有字典数组的 JSON

Posted

技术标签:

【中文标题】Alamofire:发送带有字典数组的 JSON【英文标题】:Alamofire: Send JSON with Array of Dictionaries 【发布时间】:2016-03-24 15:39:05 【问题描述】:

我有一个 JSON 格式的数据结构:

[
    "value": "1",
    "optionId": "be69fa23-6eca-4e1b-8c78-c01daaa43c88"
, 
    "value": "0",
    "optionId": "f75da6a9-a34c-4ff6-8070-0d27792073df"
]

基本上它是一个字典数组。我更喜欢使用默认的 Alamofire 方法,并且不想手动构建请求。有没有办法给 Alamofire 我的参数,Alamofire 做剩下的?

如果我手动创建所有内容,我会从服务器收到一个错误,即发送数据不正确。

    var parameters = [[String:AnyObject]]()

    for votingOption in votingOptions

        let type = votingOption.votingHeaders.first?.type

        let parameter = ["optionId":votingOption.optionID,
            "value": votingOption.votingBoolValue
        ]
        parameters.append(parameter)
    

    let jsonData = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
    let json = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments)


    if let url = NSURL(string:"myprivateurl")
        let request = NSMutableURLRequest(URL: url)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.HTTPMethod = Method.POST.rawValue
        request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])

        AlamofireManager.Configured.request(request)
            .responseJSON  response in
           //Handle result     
        
    

【问题讨论】:

关于这个问题的任何更新? 【参考方案1】:

我有同样的问题并通过这种方式解决:

我创建了一个实现 Alamofire 的 ParameterEncoding 协议的新结构:

struct JSONArrayEncoding: ParameterEncoding 
    private let array: [Parameters]

    init(array: [Parameters]) 
        self.array = array
    

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest 
        var urlRequest = try urlRequest.asURLRequest()

        let data = try JSONSerialization.data(withJSONObject: array, options: [])

        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil 
            urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
        

        urlRequest.httpBody = data

        return urlRequest
    

那么,我可以这样做:

let parameters : [Parameters] = bodies.map(  $0.bodyDictionary() )
Alamofire.request(url, method: .post, encoding: JSONArrayEncoding(array: parameters), headers: headers).responseArray  ... 

它对我有用。希望可以帮助别人。

【讨论】:

这里的身体是什么?能否请您详细解释一下参数 "my_profileid":"" "countries": [ "country_full_name": "","id": ""], "languages": ["language_full_name": "", "id": ""], "areas": ["area_full_name": "","id": ""], "profile_types": ["profile_type_full_name": "","profile_type_short_name": "" ,"id": ""], "profile_levels": ["profile_level_full_name": "","id": ""] 这是我的请求参数,但它给了我错误 响应:失败:responseSerializationFailed(原因:Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)【参考方案2】:

你可以这样做:

Alamofire.request(.POST, urlPath, parameters: params).responseJSON request, response, data in
    //YOUR_CODE

parameters[String:AnyObject],是的,Alamofire 负责其余部分。

由于您使用的是经理,因此您可以这样做

YOUR_ALAMOFIRE_MANAGER.request(.POST, url, parameters: params).responseJSON request, response, JSON in
   //enter code here

这里是源代码:

public func request(
    method: Method,
    _ URLString: URLStringConvertible,
    parameters: [String: AnyObject]? = nil,
    encoding: ParameterEncoding = .URL,
    headers: [String: String]? = nil)
    -> Request

    let mutableURLRequest = URLRequest(method, URLString, headers: headers)
    let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
    return request(encodedURLRequest)

编辑:

由于您的数据当前为[[String:AnyObject]],您需要对其进行修改,使其格式为[String:AnyObject]。一种方法是这样做["data":[[String:AnyObject]]]。不过,您可能必须更改您的 api 端点。

【讨论】:

参数采用 [String: AnyObject] 但我有 [[String:AnyObject]]。或者,如果您查看我的 JSON,您是否看到了这种可能性? 我没有看到,你总是可以做类似["data":[[String:AnyObject]]]的事情。 您必须对数据进行建模以反映 [String:AnyObject]。应该不会太难。【参考方案3】:

您可以为 JSON POST 请求提供参数编码,它将在请求正文中以 JSON 格式发送数据。

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)

这在 Alamofire github 的自述文件中有所描述 - https://github.com/Alamofire/Alamofire#post-request-with-json-encoded-parameters

let parameters = [
    "foo": [1,2,3],
    "bar": [
        "baz": "qux"
    ]
]

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)
// HTTP body: "foo": [1, 2, 3], "bar": "baz": "qux"

【讨论】:

参数采用 [String: AnyObject] 但我有 [[String:AnyObject]]。或者,如果您查看我的 JSON,您是否看到了一种可能性?

以上是关于Alamofire:发送带有字典数组的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Alamofire 多格式数据请求中发送字典数组

使用 alamofire 发布带有字典和字典数组的 JSON 对象

如何在 swift 3 中使用 Alamofire 制作和发送字典数组(JSON 格式)发送到服务器

在 Swift 中使用 Alamofire 发送包含字典对象数组的字典对象时会发生奇怪的行为?

Alamofire:创建字典数组

使用 swift 在 Alamofire 中发送带有对象数组的 JSON 作为参数