I have to post array of dictionary value like this.
{
"reservedHour": "2019-11-01T14:55+0900",
"reservedBoxSize": "sm",
"products": [{
"id": 312
}],
"boxArea": {
"id": 66
},
"type": "RENT"
}
products is Array of Json Object.
So I try this.
func requestReserveAvailableDate(type: String, reserveHour: String, boxAreaID: Int, boxSize: String, productIDs: [Int], completionHandler: #escaping (_ availableDates: [String]?, _ errorMessage: String?) -> Void) {
let parameters: [String: Any] = ["type": type,
"reservedHour": reserveHour,
"boxArea": ["id": boxAreaID],
"reservedBoxSize": boxSize,
"products": productIDs.map({ ["id": $0] })]
...
But this is not working.
I am using alamofire only for all API calls. Please help me how I can solve it.
Just try like this
var parameters: [String: Any] = [:]
parameters = ["type": type,
"reservedHour": reserveHour,
"reservedBoxSize": boxSize,
"boxArea": [],
"products": []]
var boxAreaParams:[String:Any] = [:]
boxAreaParams = ["id": boxAreaID]
parameters["boxArea"] = boxAreaParams
var productsParmas: [string: Any] = [:]
productParams = ["id": productId]
var product = parameter["products"] as? [[String: Any]] ?? [[String: Any]]()
product.append(productParams)
parameters["product"] = product
Related
I have geoJSON file:
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
40.303141,
55.9765684
],
[
40.3033449,
55.9765114
],
[
40.3034017,
55.976575
],
[
40.3031979,
55.9766321
],
[
40.303141,
55.9765684
]
]
]
]
},
"properties": {
"#id": 4305947573,
"building": "yes"
}
}
I'm interested in properties:
"properties":{"#id":4305947573,"building":"yes"}
I want parse "properties", and make structure:
struct Feature: Decodable {
let type: String
let properties: Dictionary<String, String> }
It's work good, but then i add parameter in geoJSON: "#id":4305947573
4305947573 - this is Int variable, and parser don't parse geoJSON.
I think i need modify my struct Feature. I want to parser understand and String, and Int in properties.
Help me please. Thank you
There are a number of GeoJSON swift libraries (search github) that you could use
instead of re-inventing the wheel.
If you really want to code it yourself, try this approach,
where the dynamic keys and values of properties are decoded
into a dictionary of var data: [String: Any], as shown.
Use the struct models like this:
let result = try JSONDecoder().decode(Feature.self, from: data)
Models
struct Feature: Decodable {
let type: String
var properties: Properties
// ...
}
struct Properties: Decodable {
var data: [String: Any] = [:]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DynamicKey.self)
container.allKeys.forEach { key in
if let theString = try? container.decode(String.self, forKey: key) {
self.data[key.stringValue] = theString
}
if let theInt = try? container.decode(Int.self, forKey: key) {
self.data[key.stringValue] = theInt
}
}
}
}
struct DynamicKey: CodingKey {
var intValue: Int?
init?(intValue: Int) {
self.intValue = intValue
self.stringValue = ""
}
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
}
I have this JSON string:
[
{
"name": "first_category",
"model": {
"OK": 0.49404761904761907,
"NOPE": 0.48214285714285715
}
},
{
"name": "second_category",
"model": {
"YOP": 0.389338593,
"GO": 0.20420894
}
}
]
I have created this struct to decode it:
struct JSONModel: Codable {
let name: String
let model: [String: Double]
}
The decoding:
let decodedModel = try? decoder.decode([JSONModel].self, from: Data(jsonString.utf8))
It correctly fills the array as expected, but now I would like to use this array to create a dictionary whose keys would be the JSONModel names, and values the models. This is what I expect to get:
[
"first_category": [
"OK": 0.49404761904761907,
"NOPE": 0.4821428571428571
],
"second_category": [
"YOP": 0.389338593,
"GO": 0.20420894
]
]
So I tried this:
let simplifiedModel: [String: [String: Double]] = decodedModel.flatMap { [$0.name: $0.model] }
But I'm getting this error:
Cannot convert value of type '[Dictionary<String, [String : Double]>.Element]' to closure result type '[String : [String : Double]]'
What should I do instead?
Thank you for your help
I would use reduce(into:) for this
let dictionary = decodedModel.reduce(into: [:]) {
$0[$1.name] = $1.model
}
The following two forms of data were successfully requested.
{
"ride_fare": 1000,
"km": 7
]
}
{
"ride_fare": 1000,
"km": 7,
"options": [ 0, 1, 2]
}
However, I don't know how to request a two-dimensional associative array like the one below.
How can I request it?
{
"ride_fare": 1000,
"km": 7,
"option_fares": [
{
"price": 200,
"name": "立ち寄り",
"id": 1
}
]
}
The code that I wrote:
var options = [Any]()
for option in optionFares {
let params = [
"id" : option.id ?? 0,
"name" : option.name ?? "",
"price" : option.price ?? 0
] as [String : Any]
options.append(params)
}
let faresData = [
"id" : driverOrder.id ?? 0,
"km" : driverOrder.distance ?? 0,
"option_fares" : options,
"ride_fare" : driverOrder.ride_fare ?? 0
] as [String : Any]
First, create a struct that matches the json format you want to request.
struct Params: Codable {
let rideFare, km: Int
let optionFares: [OptionFare]
enum CodingKeys: String, CodingKey {
case rideFare = "ride_fare"
case km
case optionFares = "option_fares"
}
}
struct OptionFare: Codable {
let price: Int
let name: String
let id: Int
}
And you must create a request parameter in Moya's task.
import Moya
extension APITarget: TargetType {
var task: Task {
case .yourCaseName(let price, let name, let id, let rideFare, let km):
let encoder: JSONEncoder = JSONEncoder()
let optionFareData: [OptionFare] = []
optionFareData.append(OptionFare(price, name, id))
let paramsData = Params(rideFare, km, optionFareData)
let jsonData: Data = try! encoder.encode(paramsData)
return .requestData(jsonData)
}
}
}
I got a struct like the following
struct Wrapper {
var value: [String: Any]
// type "Any" could be String, Int or [String].
// i.g. ["a": 1, "b": ["ccc"]]
// and the keys of this dictionary are not determined
}
I been struggled for quite a while😭.
Anyone has any idea how to resolve it?
You can use some library like AnyCodable
Then you can make your struct Codable by using AnyCodable class instead of Any.
struct Wrapper: Codable {
var value: [String: AnyCodable]
}
Example
let arrayWrapper: [String: Any] =
["value" :
[
"test" : ["1", "2", "3"],
"parse" : ["4", "5", "6"]]
]
let jsonData = try! JSONSerialization.data(withJSONObject: arrayWrapper, options: .prettyPrinted)
do {
let decoder = JSONDecoder()
let result = try decoder.decode(Wrapper.self, from: jsonData)
print("result:", result)
} catch let error {
print("error:", error)
}
Output
result: Wrapper(value: ["parse": AnyCodable(["4", "5", "6"]), "test": AnyCodable(["1", "2", "3"])])
I'm trying to make a post request with a body array in swift using Alamofire
postman like
and here my code
class func storeEventContact(_ id:String, type_contact:String, user_id: Int, firstname:String, lastname: String,completionHandler:RequestCompletionHandler?){
let url = "\(Endpoints.BASE)\(Endpoints.INVITE_STORE)"
let params:NSMutableDictionary? = ["id": id,
"type_contact":type_contact,
"contacts": ["user_id" : user_id, "firstname" : firstname, "lastname" : lastname]]
self.postRequest(url: url, parameters: params as? [String : Any]) { (result, error) in
self.postRequest(url: url, parameters: params as? [String : Any]) { (result, error) in
if error != nil{
completionHandler?(result, error)
return
}
let baseResponse = Mapper<BaseResponse>().map(JSONObject: result)
if !baseResponse!.status{
completionHandler?(baseResponse, error)
return
}
completionHandler?(result, error)
}
}
}
You just need to define an array, you are almost there, just need an extra set of [] in your dictionary.
let params = ["id": id,
"type_contact":type_contact,
"contacts": [
[
"user_id": user_id,
"firstname": firstname,
"lastname": lastname
]]]