在alamofire中发送对象数组

时间:2019-05-24 11:32:05

标签: swift alamofire

我需要将对象列表发送到终点。 所需类型具有以下键

{
  id: Int;
  all: Bool;
  batch: Bool;
  chapter: Bool;
  myNetwork: Bool;
  categoryId: Int;
}

api需要上述对象的列表。我像这样使用Alamofire的参数类型生成了一个列表。

[
    ["chapter": "true", "myNetwork": "false", "id": "3", "categoryId": "1", "memberId": "13", "batch": "true", "all": "true"], 
    ["categoryId": "2", "batch": "false", "myNetwork": "true", "all": "true", "id": "891", "memberId": "13", "chapter": "true"], 
    ["batch": "false", "memberId": "13", "categoryId": "3", "all": "false", "id": "1779", "myNetwork": "false", "chapter": "false"], 
    ["batch": "true", "id": "2667", "all": "false", "chapter": "true", "memberId": "13", "categoryId": "4", "myNetwork": "false"]
]

但显示错误

  

无法将类型[[[String:Any]]]的值转换为预期参数   输入“参数?” (又名“可选”)

如何使用Alamofire将此对象列表发送到API?调度请求的代码

  

Alamofire.request(“(APIManager.url)/ Privacy / Update”,方法:.post,   参数:params,编码:JSONEncoding.default,标头:   APIManager.headers)

4 个答案:

答案 0 :(得分:0)

您的参数应该像这样

["key": "value", "key": "value"]

这是一个字典,您使用的是一个字典数组,这就是为什么您会遇到错误

答案 1 :(得分:0)

如错误所示,期望Dictionary<String, Any>,但是又传递[[String : Any]] Array<Dictionary<String,Any>>

您可能想要更改它,并将字典数组(这是您要发送的数据)添加到Any的{​​{1}}部分,将其分配为密钥并发送。

您可以做的-

Dictionary<String, Any>

因此,["data" : [ ["chapter": "true", "myNetwork": "false", "id": "3", "categoryId": "1", "memberId": "13", "batch": "true", "all": "true"], ["categoryId": "2", "batch": "false", "myNetwork": "true", "all": "true", "id": "891", "memberId": "13", "chapter": "true"], ["batch": "false", "memberId": "13", "categoryId": "3", "all": "false", "id": "1779", "myNetwork": "false", "chapter": "false"], ["batch": "true", "id": "2667", "all": "false", "chapter": "true", "memberId": "13", "categoryId": "4", "myNetwork": "false"] ]] 将是您的密钥,而 value 将是您要发送的内容

注意-您可能需要相应地更改服务器代码并接受顶级词典

答案 2 :(得分:0)

将数组转换为json字符串。这是使用Alamofire时发送对象列表的最佳方法

var JSONBinData: String = ""

if let theJSONData = try?  JSONSerialization.data(
                withJSONObject: binData,
                options: .prettyPrinted
                ),
                let theJSONText = String(data: theJSONData,
                                         encoding: String.Encoding.ascii) {
                print("JSON string = \n\(theJSONText)")
                JSONBinData = theJSONText
            }

答案 3 :(得分:0)

您可以使用https://github.com/peheje/JsonSerializerSwift/blob/master/JsonSerializerSwift/JsonSerializer.swift中的这个开源类JSONSerializer

我在此类中进行了一些更改,以在现有的 JSON

中添加带有键的对象数组
import Foundation

 /// Handles Convertion from instances of objects to JSON strings. Also helps with casting strings of JSON to Arrays or Dictionaries.
open class JSONSerializer {

/**
Errors that indicates failures of JSONSerialization
- JsonIsNotDictionary:  -
- JsonIsNotArray:           -
- JsonIsNotValid:           -
*/
public enum JSONSerializerError: Error {
    case jsonIsNotDictionary
    case jsonIsNotArray
    case jsonIsNotValid
}

//http://stackoverflow.com/questions/30480672/how-to-convert-a-json-string-to-a-dictionary
/**
Tries to convert a JSON string to a NSDictionary. NSDictionary can be easier to work with, and supports string bracket referencing. E.g. personDictionary["name"].
- parameter jsonString: JSON string to be converted to a NSDictionary.
- throws: Throws error of type JSONSerializerError. Either JsonIsNotValid or JsonIsNotDictionary. JsonIsNotDictionary will typically be thrown if you try to parse an array of JSON objects.
- returns: A NSDictionary representation of the JSON string.
*/
open static func toDictionary(_ jsonString: String) throws -> NSDictionary {
    if let dictionary = try jsonToAnyObject(jsonString) as? NSDictionary {
        return dictionary
    } else {
        throw JSONSerializerError.jsonIsNotDictionary
    }
}

/**
Tries to convert a JSON string to a NSArray. NSArrays can be iterated and each item in the array can be converted to a NSDictionary.
- parameter jsonString: The JSON string to be converted to an NSArray
- throws: Throws error of type JSONSerializerError. Either JsonIsNotValid or JsonIsNotArray. JsonIsNotArray will typically be thrown if you try to parse a single JSON object.
- returns: NSArray representation of the JSON objects.
*/
open static func toArray(_ jsonString: String) throws -> NSArray {
    if let array = try jsonToAnyObject(jsonString) as? NSArray {
        return array
    } else {
        throw JSONSerializerError.jsonIsNotArray
    }
}

/**
Tries to convert a JSON string to AnyObject. AnyObject can then be casted to either NSDictionary or NSArray.
- parameter jsonString: JSON string to be converted to AnyObject
- throws: Throws error of type JSONSerializerError.
- returns: Returns the JSON string as AnyObject
*/
fileprivate static func jsonToAnyObject(_ jsonString: String) throws -> Any? {
    var any: Any?

    if let data = jsonString.data(using: String.Encoding.utf8) {
        do {
            any = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
        }
        catch let error as NSError {
            let sError = String(describing: error)
            NSLog(sError)
            throw JSONSerializerError.jsonIsNotValid
        }
    }
    return any
}

/**
Generates the JSON representation given any custom object of any custom class. Inherited properties will also be represented.
- parameter object: The instantiation of any custom class to be represented as JSON.
- returns: A string JSON representation of the object.
*/
open static func toJson(_ object: Any, prettify: Bool = false) -> String {
    var json = ""
    if (!(object is Array<Any>)) {
        json += "{"
    }
    let mirror = Mirror(reflecting: object)

    var children = [(label: String?, value: Any)]()

    if let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children) {
        children += mirrorChildrenCollection
    }
    else {
        let mirrorIndexCollection = AnyCollection(mirror.children)
        children += mirrorIndexCollection
    }

    var currentMirror = mirror
    while let superclassChildren = currentMirror.superclassMirror?.children {
        let randomCollection = AnyRandomAccessCollection(superclassChildren)!
        children += randomCollection
        currentMirror = currentMirror.superclassMirror!
    }

    var filteredChildren = [(label: String?, value: Any)]()

    for (optionalPropertyName, value) in children {

        if let optionalPropertyName = optionalPropertyName {

            if !optionalPropertyName.contains("notMapped_") {
                filteredChildren.append((optionalPropertyName, value))
            }

        }
        else {
            filteredChildren.append((nil, value))
        }
    }

    var skip = false
    let size = filteredChildren.count
    var index = 0

    var first = true

    for (optionalPropertyName, value) in filteredChildren {
        skip = false

        let propertyName = optionalPropertyName
        let property = Mirror(reflecting: value)

        var handledValue = String()

        if propertyName != nil && propertyName == "some" && property.displayStyle == Mirror.DisplayStyle.struct {
            handledValue = toJson(value)
            skip = true
        }
        else if (value is Int ||
                 value is Int32 ||
                 value is Int64 ||
                 value is Double ||
                 value is Float ||
                 value is Bool) && property.displayStyle != Mirror.DisplayStyle.optional {
            handledValue = String(describing: value)
        }
        else if let array = value as? [Int?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Double?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Float?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Bool?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? "\"\(value!)\"" : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += "\"\(value)\""
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? NSArray {
            handledValue += "["
            for (index, value) in array.enumerated() {
                if !(value is Int) &&
                   !(value is Int32) &&
                   !(value is Int64) &&
                   !(value is Double) && !(value is Float) && !(value is Bool) && !(value is String) {
                    handledValue += toJson(value)
                }
                else {
                    handledValue += "\(value)"
                }
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if property.displayStyle == Mirror.DisplayStyle.class ||
            property.displayStyle == Mirror.DisplayStyle.struct ||
            String(describing: value).contains("#") {
            handledValue = toJson(value)
        }
        else if property.displayStyle == Mirror.DisplayStyle.optional {
            let str = String(describing: value)
            if str != "nil" {
                // Some optional values cannot be unpacked if type is "Any"
                // We remove the "Optional(" and last ")" from the value by string manipulation
                var d = String(str).dropFirst(9)
                d = d.dropLast(1)
                handledValue = String(d)
            } else {
                handledValue = "null"
            }
        }
        else {
            handledValue = String(describing: value) != "nil" ? "\"\(value)\"" : "null"
        }

        if !skip {

            // if optional propertyName is populated we'll use it
            if let propertyName = propertyName {
                json += "\"\(propertyName)\": \(handledValue)" + (index < size-1 ? ", " : "")
            }
            // if not then we have a member an array
            else {
                // if it's the first member we need to prepend ]
                if first {
                    json += "["
                    first = false
                }
                // if it's not the last we need a comma. if it is the last we need to close ]
                json += "\(handledValue)" + (index < size-1 ? ", " : "]")
            }

        } else {
            json = "\(handledValue)" + (index < size-1 ? ", " : "")
        }

        index += 1
    }

    if !skip {
        if (!(object is Array<Any>)) {
            json += "}"
        }
    }

    if prettify {
       let jsonData = json.data(using: String.Encoding.utf8)!
       let jsonObject = try! JSONSerialization.jsonObject(with: jsonData, options: [])
       let prettyJsonData = try! JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
       json = NSString(data: prettyJsonData, encoding: String.Encoding.utf8.rawValue)! as String
    }

    return json
}
/**
 Generates the JSON representation given any custom object of any custom class. Inherited properties will also be represented.
 - parameter object:    The instantiation of any custom class to be represented as JSON.
 - returns: A string JSON representation of the object.
 */
open static func toJson(key: String, _ object: Any, existingJson: String = "", prettify: Bool = false) -> String {
    var json = ""
    if (!(object is Array<Any>)) {
        json += "{ "
    }
    let mirror = Mirror(reflecting: object)

    var children = [(label: String?, value: Any)]()

    if let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children) {
        children += mirrorChildrenCollection
    }
    else {
        let mirrorIndexCollection = AnyCollection(mirror.children)
        children += mirrorIndexCollection
    }

    var currentMirror = mirror
    while let superclassChildren = currentMirror.superclassMirror?.children {
        let randomCollection = AnyRandomAccessCollection(superclassChildren)!
        children += randomCollection
        currentMirror = currentMirror.superclassMirror!
    }

    var filteredChildren = [(label: String?, value: Any)]()

    for (optionalPropertyName, value) in children {

        if let optionalPropertyName = optionalPropertyName {

            if !optionalPropertyName.contains("notMapped_") {
                filteredChildren.append((optionalPropertyName, value))
            }

        }
        else {
            filteredChildren.append((nil, value))
        }
    }

    var skip = false
    let size = filteredChildren.count
    var index = 0

    var first = true

    for (optionalPropertyName, value) in filteredChildren {
        skip = false

        let propertyName = optionalPropertyName
        let property = Mirror(reflecting: value)

        var handledValue = String()

        if propertyName != nil && propertyName == "some" && property.displayStyle == Mirror.DisplayStyle.struct {
            handledValue = toJson(value)
            skip = true
        }
        else if (value is Int ||
            value is Int32 ||
            value is Int64 ||
            value is Double ||
            value is Float ||
            value is Bool) && property.displayStyle != Mirror.DisplayStyle.optional {
            handledValue = String(describing: value)
        }
        else if let array = value as? [Int?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Double?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Float?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Bool?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String?] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += value != nil ? "\"\(value!)\"" : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String] {
            handledValue += "["
            for (index, value) in array.enumerated() {
                handledValue += "\"\(value)\""
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? NSArray {
            handledValue += "["
            for (index, value) in array.enumerated() {
                if !(value is Int) &&
                    !(value is Int32) &&
                    !(value is Int64) &&
                    !(value is Double) && !(value is Float) && !(value is Bool) && !(value is String) {
                    handledValue += toJson(value)
                }
                else {
                    handledValue += "\(value)"
                }
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if property.displayStyle == Mirror.DisplayStyle.class ||
            property.displayStyle == Mirror.DisplayStyle.struct ||
            String(describing: value).contains("#") {
            handledValue = toJson(value)
        }
        else if property.displayStyle == Mirror.DisplayStyle.optional {
            let str = String(describing: value)
            if str != "nil" {
                // Some optional values cannot be unpacked if type is "Any"
                // We remove the "Optional(" and last ")" from the value by string manipulation
                var d = String(str).dropFirst(9)
                d = d.dropLast(1)
                handledValue = String(d)
            } else {
                handledValue = "null"
            }
        }
        else {
            handledValue = String(describing: value) != "nil" ? "\"\(value)\"" : "null"
        }

        if !skip {

            // if optional propertyName is populated we'll use it
            if let propertyName = propertyName {
                json += "\"\(propertyName)\": \(handledValue)" + (index < size-1 ? ", " : "")
            }
                // if not then we have a member an array
            else {
                // if it's the first member we need to prepend ]
                if first {
                    json += "["
                    first = false
                }
                // if it's not the last we need a comma. if it is the last we need to close ]
                json += "\(handledValue)" + (index < size-1 ? ", " : "]")
            }

        } else {
            json = "\(handledValue)" + (index < size-1 ? ", " : "")
        }

        index += 1
    }

    if !skip {
        if (!(object is Array<Any>)) {
            json += "}"
        }
    }

    if !existingJson.isEmpty {
        var JSON = existingJson
        JSON.removeLast()
        JSON = JSON + ", \"\(key)\": " + json + " }"
        if prettify {
            return prettyJson(json: JSON)
        }
        return JSON
    } else if existingJson.isEmpty {
        if prettify {
            return prettyJson(json: "{ \"\(key)\": " + json + " }")
        }
        return "{ \"\(key)\": " + json + " }"
    }
    return prettyJson(json: json)
}

private static func prettyJson(json: String) -> String {
    let jsonData = json.data(using: String.Encoding.utf8)!
    let jsonObject = try! JSONSerialization.jsonObject(with: jsonData, options: [])
    let prettyJsonData = try! JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
    return NSString(data: prettyJsonData, encoding: String.Encoding.utf8.rawValue)! as String
}

}

这是使用此类的代码

let params = [ "some key": "some value"]
     if let theJSONData = try? JSONSerialization.data(withJSONObject: params, options: []) {
         let theJSONText = String(data: theJSONData, encoding: .ascii)
         let json = JSONSerializer.toJson(key: "Products", Cart.sharedInstance.products, existingJson: theJSONText!, prettify: true)
         print("JSON string = \(json)")
         let finalParams = json.convertToDictionary()
         // pass finalParams as Alamofire param
}

用对象数组替换 Cart.sharedInstance.products ,并用键替换 Products

您可以根据需要查看重载的方法。

希望您得到想要的结果。