How to create a dictionary with 2 arrays inside? - ios

I want to create a dictionary with the next structure, for sending it via Alamofire as JSON to a server:
{
"user": {
"firstName": "fName",
"lastName": null,
"img": null,
"books": [
{
"id": 1
}, {
"id": 2
}
]
},
"locale": "en",
"gender": "male"
}
For this structure of JSON, I've tried the next:
let parameters: [[String: [String: String]], [String: String]]
but there a lot closures, so I confused with it. Can you help me with creating this structure?

The collection types in the Swift standard library only support homogenous collections, i.e. all elements in a collection must have the same type. So you cannot declare an array whose first element is of type [String: [String: String]] and whose second element is of type [String: String] if that is what you wanted.
This works:
let parameters = [
"user": [
"firstName": "fName",
"lastName": NSNull(),
"img": NSNull(),
"books": [
[ "id": 1],
[ "id": 2]
]
],
"locale": "en",
"gender": "male"
]
The type of parameters is [String: NSObject] where NSObject is the superclass of all the values in the dictionary. Note the use of NSNull to model null values, which is what NSJSONSerialization expects.

Related

Swift nested dictionary returns always optionals

Im trying to send a nested dictionary to an API. Even though none of the properties inside address is declared as optional, when I print this dictionary everything inside address is optional and the rest is non-optional. How to avoid this? Will creating a model and encoding that model to a dictionary result in the same behaviour?
var data = [
"individual": [
"address": [
"city": placemark.locality,
"country": placemark.isoCountryCode,
"line1": line1,
"line2": line2,
"postal_code": placemark.postalCode,
"state": placemark.administrativeArea
],
"dob": dob,
"email": email,
"first_name": firstName,
"last_name": lastName,
"phone": phone
],
"country": account_number.prefix(2),
"currency": "EUR",
"account_number": account_number
] as [String : Any]

How can I convert JSON to Swift Dictinary inorder to make an HTTP POST

I am having issues to successfully structure my json data into a swift dictionary inorder to send my HTTP body via an API
This is how my Json is structured:
{
"idNo": "string",
"name": "string",
"isRegistered": true,
"customMessage": "string",
"riskStatus": "Low",
"exposureBasedRiskStatus": "Low",
"symptomBasedRiskStatus": "Low",
"riskMessage": "string",
"doYouHaveATemperature": true,
"temperature": 0,
"asessmentQuestion": [
{
"question": "string",
"answer": "string",
"createdBy": "string"
},
{
"question": "string",
"answer": "string",
"createdBy": "string"
},
{
"question": "string",
"answer": "string",
"createdBy": "string"
},
{
"question": "string",
"answer": "string",
"createdBy": "string"
},
{
"question": "string",
"answer": "string",
"createdBy": "string"
}
]
}
the object "asessmentQuestion" is an array of different questions, can't seem to figure out how to convert this structure to a swift dictionary or another recommended format for me to be able to post my data. My API is always saying bad request and I'm pretty sure I am not correctly mapping the json data.
this is a snippet of how I am attempting to map my json data:
var dictionary = [String:Any]()
dictionary["1. How old are you?"] = model.riskExposureBasedAssessment[0].answer
dictionary["2. Have you ever visited a COVID affected country?"] = model.riskExposureBasedAssessment[1].answer
dictionary["3. do you frequently experience flu like symptoms?"] = model.riskExposureBasedAssessment[2].answer
dictionary["4. Where you providing care in a non-health setting for a person with symptomatic COVID-19 infection"] = model.riskExposureBasedAssessment[3].answer
dictionary["5. Did you come in close contact* with a person with symptomatic laboratory-confirmed COVID-19 infection?"] = model.riskExposureBasedAssessment[4].answer
let parameters = [
"idNo": model.id,
"name": model.name,
"isRegistered": model.isRegistered,
"customMessage": model.customResponse,
"riskStatus": model.riskStatus,
"exposureBasedRiskStatus": model.exposureBasedRiskStatus,
"symptomBasedRiskStatus": model.symptomBasedRiskStatus,
"riskMessage": model.riskMessage,
"doYouHaveATemperature": model.doYouHaveATemperature,
"temperature": model.temperature,
"exposureBasedAssessments": dictionary
] as [String:Any]
let postData = try? JSONSerialization.data(withJSONObject: parameters)
It's an array of dictionary, so :
var dictionaries: [[String: Any]] = []
// Populate dictionaries
// ...
let parameters = [
"idNo": model.id,
"name": model.name,
"isRegistered": model.isRegistered,
"customMessage": model.customResponse,
"riskStatus": model.riskStatus,
"exposureBasedRiskStatus": model.exposureBasedRiskStatus,
"symptomBasedRiskStatus": model.symptomBasedRiskStatus,
"riskMessage": model.riskMessage,
"doYouHaveATemperature": model.doYouHaveATemperature,
"temperature": model.temperature,
"exposureBasedAssessments": dictionaries
] as [String:Any]
Then, to populate it:
var dict1: [String: Any] = [:]
dict1["question"] = "1. How old are you?"
dict1["answer"] = model.riskExposureBasedAssessment[0].answer
dictionaries.append(dict1)
var dict2: [String: Any] = [:]
dict2["question"] = "2. Have you ever visited a COVID affected country?"
dict2["answer"] = model.riskExposureBasedAssessment[1].answer
dictionaries.append(dict2)
...
or
var dict1: [String: Any] = ["question": "1. How old are you?",
"answer": model.riskExposureBasedAssessment[0].answer]
dictionaries.append(dict1)
var dict2: [String: Any] = ["question": "2. Have you ever visited a COVID affected country?"",
"answer": model.riskExposureBasedAssessment[1].answer]
dictionaries.append(dict2)
...
But, I guess you have can retrieve the question from model.riskExposureBasedAssessment[n],
Instead of "1. How old are you?", can't you do model.riskExposureBasedAssessment[0].question?
If that's the case, you can use a for loop:
so I'd go with:
for aQuestionModel in model.riskExposureBasedAssessment {
let questionDict = ["question": aQuestionModel.question,
"answer": aQuestionModel.answer]
dictionaries.append(questionDict)
}
Or, once you master basic algorithm, closures, and map():
var dictionaries = model.riskExposureBasedAssessment.map { ["question": $0.question, "answer": $0.answer] }
It's missing the "createdBy", I don't know where to find it and if it's optional, but I think you should be able to add it if needed.
NotaBene:
Code not tested against a compiler. It should work, at maybe one or two typos.

How can I post an order into woocommerce using Alamofire?

I am trying to create an order from iOS to woo commerce using Alamofire. I am searching for a proper solution.
After trying to create an order I get this error:
{
code = "woocommerce_rest_cannot_create";
data = {
status = 401;
};
message = "Sorry, you are not allowed to create resources.";
}
Code:
let parameters: [String: AnyObject] = [
"consumer_key":"*******" as AnyObject, // here is my user name
"consumer_secret":"*******" as AnyObject, // here is my secret key
"shipping_total": "120.00" as AnyObject,
"total": "6015.00" as AnyObject,
"customer_id": 0 as AnyObject,
"billing": [
"first_name": "Faizul",
"last_name": "karim",
"company": "somecompany",
"address_1": "someAddress",
"address_2": "someAddress",
"city": "Dhaka",
"state": "Dhaka",
"postcode": "1203",
"country": "bd",
"email": "faizulkarim28#gmail.com",
"phone": "001929838939"
] as AnyObject,
"shipping": [
"first_name": "Faizul",
"last_name": "karim",
"company": "somecompany",
"address_1": "someAddress",
"address_2": "someAddress",
"city": "Dhaka",
"state": "Dhaka",
"postcode": "1203",
"country": "bd",
] as AnyObject,
"line_items":[
"id": 388,
"name": "Mens Casual Blazer - 40",
"product_id": 55677,
"variation_id": 57619,
"quantity": 1,
"tax_class": "",
"subtotal": "5895.00",
"subtotal_tax": "0.00",
"total": "5895.00",
"total_tax": "0.00",
] as AnyObject
]
Alamofire.request("https://infinitymegamall.com/wp-json/wc/v2/orders",method: .post, parameters: parameters)
.responseJSON{ response in
if let json = response.result.value {
print(json)
}
}
Are you sure your API Keys have write permissions? If GET works, it's possible that the key allows read only. Double check the permissions in your Woocommerce API Settings.

create a dictionary contains Array and Dictionary in swift 4

I just want to create an API JSON Structure. The following are the post body keys and objects. Are there any methods like object with keys and values similar to Objective C in Swift 4?
{
"name": "switch 1",
"type": "Switch",
"gatewayId":515,
"serialKey": "98:07:2D:48:D3:56",
"noOfGangs": 4,
"equipments": [
{
"name": "light",
"type": "Light",
"port": "1"
},
{
"name": "television",
"type": "Television",
"port": "3"
}
]
}
You can create the dictionary literally by annotating the type and replace the curly braces with square brackets
let dict : [String:Any] = ["name": "switch 1", "type": "Switch", "gatewayId":515, "serialKey": "98:07:2D:48:D3:56", "noOfGangs": 4, "equipments": [[ "name": "light", "type": "Light", "port": "1" ], ["name": "television", "type": "Television", "port": "3" ]]]
Or build it:
var dict : [String:Any] = ["name": "switch 1", "type": "Switch", "gatewayId":515, "serialKey": "98:07:2D:48:D3:56", "noOfGangs": 4]
var equipments = [[String:String]]()
equipments.append(["name": "light", "type": "Light", "port": "1" ])
equipments.append(["name": "television", "type": "Television", "port": "3" ])
dict["equipments"] = equipments
how to create Dictionary
var populatedDictionary = ["key1": "value1", "key2": "value2"]
this how to create Array
var shoppingList: [String] = ["Eggs", "Milk"]
you can create Dictionary by this type
var dictionary = [Int:String]()
dictionary.updateValue(value: "Hola", forKey: 1)
dictionary.updateValue(value: "Hello", forKey: 2)
dictionary.updateValue(value: "Aloha", forKey: 3)
// anather example
var dict = [ 1 : "abc", 2 : "cde"]
dict.updateValue("efg", forKey: 3)
print(dict)
your JSON
let dic :[String:Any] = ["name": "switch 1", "type": "Switch", "gatewayId":515, "serialKey": "98:07:2D:48:D3:56", "noOfGangs": 4, "equipments": [ [ "name": "light", "type": "Light", "port": "1" ],
[ "name": "television", "type": "Television", "port": "3" ] ] ]

How to sort multidimensional array in swift?

I need your help. I did an array, and when I launch my application on different devices or simulator, this array sorted into different types, but I need the same order on each device. How to do that?
var settings = [String: [ [String: String] ]]()
settings = [ "cards":[ ], "groups":[ ] ]
...
for card in db.prepare(table.order(orderN.asc)) {
settings["cards"]?.append(["id":String(card[id]), "group_id":String(card[group_id]), "service":card[service], "bgcolor":card[bgcolor], "logoimg":card[logoimg]!, "balance_desc":card[balance_desc], "balance":"0.0", "balance_id":String(card[balance_id]), "uniqueID":card[uniqueID], "balance_currency":String(card[balance_currency]), "orderN":String(card[orderN])])
}
...
for group in db.prepare(table.order(orderN.asc)) {
settings["groups"]?.append(["name":group[name]!,"id":String(group[id]),"orderN":String(group[orderN])])
}
...
For example,
On the first device
print(settings) // ["cards": [["orderN": "0", "bgcolor": "0.0, 0.0, 0.0, 1.0", "balance": "0.0", "logoimg": "example.com/images/img.png", "uniqueID": "00a2413f74f4a3f186e439a67057de67", "group_id": "2", "id": "1", "service": "servicename", "balance_desc": "Description", "balance_id": "1", "balance_currency": "1"]], "groups": [["orderN": "0", "name": "GroupName", "id": "2"]]]
On the second device
print(settings) // ["cards": [["orderN": "0", "uniqueID": "00a2413f74f4a3f186e439a67057de67", "service": "servicename", "id": "1", "bgcolor": "0.0, 0.0, 0.0, 1.0", "balance_currency": "1", "balance": "0.0", "group_id": "2", "logoimg": "example.com/images/img.png", "balance_id": "1", "balance_desc": "Description"]], "groups": [["id": "2", "orderN": "0", "name": "GroupName"]]]
Thank you for you attention.
That's because settings is not an Array, it's Dictionary. Order of key-value pairs in dictionary is not defined.
If you need some particular order, you should reimplement settings, probably make them separate struct or class, because you'll have a hard time working with nested dictionaries.

Resources