Recursive URL parameters construction - ios

I have a NSDictionary parameters written like this :
{
"aKey" : [
{
"associated_values" : [
42,
43,
],
"internal_id" : 3
}
],
"another_Key" : false
}
Is there a simple way to construct a URL with is formatted this way for a GET method :
https://www.url.com/another_key=false?aKey[0][internal_id]=3&aKey[0][associated_values][0]=42&aKey[0][associated_values][1]=43
We can imagine that associated_values can also contains subjson

Related

Swift Error: Consecutive statements on a line must be separated by ';'

let email = MUser.sharedInstance.getUserEmail()
let json = [
"listIds": [""],
"contacts": [{ "email" : "\(email)" }]
];
I'm getting the error Consecutive statements on a line must be separated by ';' when running the code above. What am I doing wrong?
The problem is the dictionary email: email where {, } are not recognised keywords You can define your json like this :
let json = [
"""
"listIds": [""],
"contacts": [ {"email" : "\(email)" }]
"""
];
or if you prefer to construct your dictionary in contacts with code, you could do something like below:
let json = [
"listIds": [""],
"contacts": [[ "email" : "\(email)" ]]
];

How to consume an API response with Swift

I am trying to make an API request to get an API response I am getting all the elements but I am facing braces issue I want a whole response and "order_devices" key, in {} braces but I am getting these in [] braces.
the array in which i am passing value,
var popUpArray :[[String:AnyObject]] = []
then on btn click i am saving values in dictionary
#IBAction func btnSave(_ sender: Any) {
let popupDict = (["quantity": Int(txtEnterQuantity.text!), "name": lblDeviceName.text,"id": deviceDict["id"], "region":1, "system_integrated":1 ])as! [String:AnyObject]
and then passing the same dictionary value as parameter
let passDict = [
"dealer_id":dropDownId!,
"client_id":dropDownId!,
"distributor_id":searchBarId!,
"emp_id":UserId,
"comments":CommentKey!,
"accepted_by":0,
"valid_from":strDate!,
"valid_upto": 0,
"order_devices":popupDict
] as [String : Any]
if Reachability.isConnectedToNetwork() {
showActivityIndicator()
Alamofire.request("http://13.232.230.41/IAC_CRM/public/api/createOrder", method: .post, parameters: passDict, encoding: JSONEncoding.default, headers: [:])
.responseJSON { (response) in
i am getting this response ,
[
"comments": "demo",
"dealer_id": 3,
"valid_from": "6-3-2019",
"distributor_id": 72,
"client_id": 3,
"accepted_by": 0,
"emp_id": 33,
"valid_upto": 0
"order_devices":
[
[
"id": 1,
"quantity": 10,
"region": 1,
"system_integrated": 1
]
,
[
"id": 2,
"quantity": 12,
"region": 1,
"system_integrated": 1
]
]
]
i want this response,
{ "dealer_id":"1", "client_id":"2", "distributor_id":"2",
"emp_id":"1", "comments":"IAC test device comments", "accepted_by":0,
"valid_from":"2019-01-24", "valid_upto":"1", "order_devices":[
{
"device_id":"1",
"quantity":"1", "region":1, "system_integrated":1
}
,
{
"device_id":"2",
"quantity":"1"
"region":1,
"system_integrated":1
}
] }
means i want whole response and "order_devices" key in "curly braces"{} .
There is nothing wrong with request or response, your are getting response what your API is returning, You should ask you backend developer Or Api Provider to Give you response in form of your requirement i mean proper formatted Right now its in form of Array.

Alamofire send Array of Dictionaries in a parameter

I have a POST API in which I send multiple parameters, one of those parameters has to be an array of dictionaries.
let arr = [
[
"id" : "1",
"price" : "10"
],
[
"id" : "2",
"price" : "20"
]
]
let params : Parameters = [
"param1" : "anyvalue1",
"param2" : "anyvalue2",
"param3" : arr,
]
When I use these parameters in Alamofire Request and hit the API, print(res.result.value) always returns unknown. Can anyone help me with this. Following is the way of requesting the API
Alamofire.request(url, method:.post, parameters: params).responseJSON{(res) in
print(res.result.value) //always shows 'unknown' as output
}
Try to make params a Dic of [String :Any ] like that :
let params : [String:Any] = [
"param1" : "anyvalue1",
"param2" : "anyvalue2",
"param3" : arr,
]

Adding to dictionary dynamically

I 'm having an array of dictionary like so...
[
{
"id" : "3",
"sellingPrice" : "520",
"quantity" : "15"
},
{
"id" : "5",
"sellingPrice" : "499",
"quantity" : "-1"
},
{
"id" : "8",
"sellingPrice" : "500",
"quantity" : "79"
}
]
Now I want to add to the dictionary another key called remaining_balance with a value of 420,499 & 500 respectively. How can I achieve this..? Hope somebody can help...
It seems like you want to add a value to your dictionary that is an array:
var arrDict = Array<Dictionary<String,Any>>() //Your array
arrDict.append(["id":"3","sellingPrice":"520","quantity":"13"])
arrDict.append(["id":"5","sellingPrice":"43","quantity":"32"])
arrDict.append(["id":"8","sellingPrice":"43","quantity":"33"])
let arrValue = ["420","499","500"] //Your remaining value in array
print("Before ",arrDict)
for (index,dict) in arrDict.enumerated() {
var dictCopy = dict //assign to var variable
dictCopy["remaining_balance"] = arrValue[index]
arrDict[index] = dictCopy //Replace at index with new dictionary
}
print("After ",arrDict)
EDIT
If you are able keep an index of an array it would be possible,
Assuming that you have the index of an array
var dictCopy = arrDict[index]
dictCopy["remaining_balance"] = "666" //Your calculated value
arrDict[index] = dictCopy //Replace at index with new dictionary
var newKV = [["remaining_balance": "420"],["remaining_balance": "490"],["remaining_balance": "500"]]
let array = [["id":"3", "sellingPrice":"520", "quantity":"15"], ["id":"5", "sellingPrice":"520", "quantity":"15"], ["id":"8", "sellingPrice":"520", "quantity":"15"]]
let newArray = array.enumerated().map { (index : Int, value: [String: String]) -> [String: String] in
var dic = value
dic.merge(newKV[index]) { (_, new) -> String in
new
}
return dic
}
You could achieve it by mapping your array:
var myArray = [["id": "3", "sellingPrice": "520", "quantity" : "15"], ["id": "5", "sellingPrice": "499", "quantity" : "-1"], ["id": "8", "sellingPrice": "500", "quantity" : "79"]]
print(myArray)
/*
[["id": "3", "sellingPrice": "520", "quantity": "15"],
["id": "5", "sellingPrice": "499", "quantity": "-1"],
["id": "8", "sellingPrice": "500", "quantity": "79"]]
*/
print("___________________")
var remainingBalanceDesriedValue = 420
myArray = myArray.map { (dict: [String: String]) -> [String: String] in
var copyDict = dict
copyDict["remaining_balance"] = "\(remainingBalanceDesriedValue)"
remainingBalanceDesriedValue = (remainingBalanceDesriedValue == 420) ? 499 : (remainingBalanceDesriedValue == 499) ? 500 : 420
return copyDict
}
print(myArray)
/*
[["sellingPrice": "520", "quantity": "15", "id": "3", "remaining_balance": "420"],
["sellingPrice": "499", "quantity": "-1", "id": "5", "remaining_balance": "499"],
["sellingPrice": "500", "quantity": "79", "id": "8", "remaining_balance": "500"]]
*/
Let's assume you have an array of dictionaries like so:
var arrayOfDictionaries = [
[
"id": 3,
"sellingPrice": 520,
"quantity": 15
]
]
It is important that arrayOfDictionaries is not a let constant, otherwise it is considered immutable and you can not call append on it.
Now you init a new dictionary like:
let newDictionary = [
"id": 10,
"remaining_balance": 420,
"quantity": 15
]
Now add the newDictionary like
arrayOfDictionaries.append(newDictionary)
If the order is important
If the order is important there are a couple of ways to go about that.
When calling append the new value (in this case the new dictionary) will always be inserted at the bottom of the array.
If for some reason you can not call append in the correct order you could use insert, which inserts your dictionary at a specific position.
Yet another way is to append the values wildly and after you are done, call sort on the array.
Improvement Tips
Notice that for the values I did not use strings, as you only have numbers like "id" : 30.
Also, if you want the second key to be called remaining_balance you should call the first key selling_price instead of sellingPrice. Because of conistency.
Alternative approach
As far as I have understood you are trying to implement some software that is responsibly for selling some products.
I think you are tackling this problem from a completely wrong side.
I think you should read about database relationships. Selling products actually is a very common problem.
Maybe this will help you. I would offer a possible solution myself, but I think this misses the point of your question.
If you decide to use the database approach, you won't necessarily have to use a database. You can take the approach and implement it using simple structs/classes/arrays.
I noticed this question lacks an extension answer, yes.. I'm gonna be that guy, so here it is. This could be made more generic by supporting other types of dictionaries, feel free to pitch in ;)
Inspiration from #eason's answer.
var newKV = [["remaining_balance": "420"],["remaining_balance": "490"],["remaining_balance": "500"]]
var array = [["id":"3", "sellingPrice":"520", "quantity":"15"], ["id":"5", "sellingPrice":"520", "quantity":"15"], ["id":"8", "sellingPrice":"520", "quantity":"15"]]
extension Array where Element == [String: String] {
enum UniquingKeysStrategy {
case old
case new
}
mutating func merge(with target: Array<Element>, uniquingKeysWith: UniquingKeysStrategy = .new) {
self = self.merged(with: target)
}
func merged(with target: Array<Element>, uniquingKeysWith strategy: UniquingKeysStrategy = .new) -> Array<Element> {
let base = self.count > target.count ? self : target
let data = self.count > target.count ? target : self
return data.enumerated().reduce(into: base, {
result, data in
result[data.offset]
.merge(data.element, uniquingKeysWith: {
old, new in
if strategy == .new { return new }
return old
})
})
}
}
let mergedArrays = newKV.merged(with: array, uniquingKeysWith: .old)
array.merge(with: newKV)
Happy Coding :)

json parsing in swift

Here is my Json
{
"id": "63",
"name": "Magnet",
"price": "₹1250",
"description": "",
"image": [
"catalog/IMG-20150119-WA0012_azw1e3ge.jpg",
"catalog/IMG-20150119-WA0029_6mr3ndda.jpg",
"catalog/IMG-20150119-WA0028_ooc2ea52.jpg",
"catalog/IMG-20150119-WA0026_4wjz5882.jpg",
"catalog/IMG-20150119-WA0024_e38xvczi.jpg",
"catalog/IMG-20150119-WA0020_vyzhfkvf.jpg",
"catalog/IMG-20150119-WA0018_u686bmde.jpg",
"catalog/IMG-20150119-WA0016_c8ffp19i.jpg"
],
"thumb_image": [
"cache/catalog/IMG-20150119-WA0012_azw1e3ge-300x412.jpg",
"cache/catalog/IMG-20150119-WA0029_6mr3ndda-300x412.jpg",
"cache/catalog/IMG-20150119-WA0028_ooc2ea52-300x412.jpg",
"cache/catalog/IMG-20150119-WA0026_4wjz5882-300x412.jpg",
"cache/catalog/IMG-20150119-WA0024_e38xvczi-300x412.jpg",
"cache/catalog/IMG-20150119-WA0020_vyzhfkvf-300x412.jpg",
"cache/catalog/IMG-20150119-WA0018_u686bmde-300x412.jpg",
"cache/catalog/IMG-20150119-WA0016_c8ffp19i-300x412.jpg"
],
"specifications": [
{
"Fabrics": [
"Pure chiffon straight cut suits 48" length"
]
},
{
"MOQ": [
"Minimum 10"
]
}
]
}
In above json string the "specification" arraylist has dynamic number of key and each key has dynamic number of values
So how can parse this? Please help if anyone knows this...
Thanks in advance
There are multiple ways to do parsing. In your case specifications should be an array, so you'll be able to loop on each items.
You might want to :
Create your own JSON parse class / methods ;
Use an existing library to parse JSON.
For the second option, you can give a look at the following :
https://github.com/Wolg/awesome-swift#jsonxml-manipulation
var yourJson = data as? NSDictionary
if let id = yourJson.valueForKey("id") as String
{
//save your id from json
}
if let name = yourJson.valueForKey("name") as String
{
//save your name
}
...
if let images = yourJson.valueForKey("image") as NSArray
{
for im in images
{
//save image
}
//the same for all othe images
}
... And so on...
You should also watch some tutorials, to understand the basics of JSON parsing..
https://www.youtube.com/watch?v=MtcscjMxxq4

Resources