Turn an array into a escaped string - ios

I have an array of dictionaries like this one.
[["updated_at": , "expected_qty": 1, "parts_id": 1, "mappingType": service, "description": , "name": Epoxy, "created_at": , "price": 0, "win_service_id": 1, "id": 1, "mappingID": 1], ["updated_at": , "expected_qty": 1, "parts_id": 2, "mappingType": service, "description": , "name": Wood for Lami, "created_at": , "price": 0, "win_service_id": 1, "id": 2, "mappingID": 1]]
I need to make this entire array into an escaped string. Something like this.
"[{\"updated_at\":\"\",\"expected_qty\":1,\"parts_id\":1,\"mappingType\":\"service\",\"description\":\"\",\"name\":\"Epoxy\",\"created_at\":\"\",\"price\":0,\"win_service_id\":1,\"id\":1,\"mappingID\":1},{\"updated_at\":\"\",\"expected_qty\":1,\"parts_id\":2,\"mappingType\":\"service\",\"description\":\"\",\"name\":\"Wood for Lami\",\"created_at\":\"\",\"price\":0,\"win_service_id\":1,\"id\":2,\"mappingID\":1}]"
I know you can convert an array to a string using array.description but I don't know how to escape those characters within it. I searched a lot but I couldn't find a method that does this either.
I tried adding a string extension to do something like this.
extension String {
var escaped: String {
return self.stringByReplacingOccurrencesOfString("\"", withString: "\\\"")
}
}
The result is this.
[[\"updated_at\": , \"expected_qty\": 1, \"parts_id\": 3, \"mappingType\": service, \"description\": , \"name\": Sill, \"created_at\": , \"price\": 0, \"win_service_id\": 8, \"id\": 3, \"mappingID\": 8]]
It looks like it's almost the expected output but notice the inner pairs of square brackets. Those must be the curly brackets.
So is there a better way to do this?

You can convert your dictionary into json using NSJSONSerialization. Try the following code out
let dict = ["key":"value","key1":"0","key2":"1"] as Dictionary<String, AnyObject>
let data = try? NSJSONSerialization.dataWithJSONObject(dict, options:NSJSONWritingOptions.PrettyPrinted)
var datastring = String(data: data!, encoding: NSUTF8StringEncoding)

Related

JSONDecoder can't decode Array but can decode String

I have a struct that I would like to parse from Json:
struct Subsidiary: Decodable {
let id: Int?
let subsidiary_ref: String?
let name: String?
let address: String?
}
I try to parse it like:
let sub: [Subsidiary] = try! JSONDecoder().decode([Subsidiary].self, from: data)
where data is Data type from
session.dataTask(with: urlRequest) { (data, response, error) in
and it gives me an error
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a string/data instead.", underlyingError: nil))
If I do it like this:
let sub: String = try! JSONDecoder().decode(String.self, from: data)
it works and it gives me son
[
{"id": 5913, "subsidiary_ref": "0000159", "name": "Mercator Hipermarket Koper", "address": "Poslov.98-Koper,Dolinska C", "city": "Koper", "coordinates_x": null, "coordinates_y": null, "phone_number": "+386 56-636-800", "frequency": "A", "channel": "Food", "subchannel": "Hypermarket", "customer": 7, "day_planned": true, "badge_visible": true, "open_call": true, "number_of_planned": 13, "number_of_calls": 22, "last_call_day": 3, "notes": " notesi ki ne smejo nikoli zginiti bla marko bdsa"},
{"id": 5870, "subsidiary_ref": "0000773", "name": "Kompas Shop Pe Ferneti?i", "address": "Partizanska 150", "city": "Se?ana", "coordinates_x": null, "coordinates_y": null, "phone_number": "+386 57-380-636", "frequency": "A", "channel": "Food", "subchannel": "Supermarket", "customer": 17, "day_planned": true, "badge_visible": true, "open_call": true, "number_of_planned": 13, "number_of_calls": 1, "last_call_day": 1, "notes": null},...
]
What is wrong with my code?
EDIT:
I figure out, that if I create a string variable, and then convert this string value to data it works even with Subsidiary struct.
So something should be wrong with the data variable.
The fact that you can decode a String.self and get your JSON printed means that the root of the JSON is a string. The JSON you got, in text form, probably looks like this:
"[\r\n {\"id\": 5913, \"subsidiary_ref\": \"0000159\", \"name\": \"Mercator Hipermarket Koper\", \"address\": \"Poslov.98-Koper,Dolinska C\", \"city\": \"Koper\", \"coordinates_x\": null, \"coordinates_y\": null, \"phone_number\": \"+386 56-636-800\", \"frequency\": \"A\", \"channel\": \"Food\", \"subchannel\": \"Hypermarket\", \"customer\": 7, \"day_planned\": true, \"badge_visible\": true, \"open_call\": true, \"number_of_planned\": 13, \"number_of_calls\": 22, \"last_call_day\": 3, \"notes\": \" notesi ki ne smejo nikoli zginiti bla marko bdsa\"}\r\n]"
Note that the actual JSON you want is put in ""s, so all the special characters are escaped.
The web service has given the JSON in a very weird way...
To get the actual JSON data decoded, you need to get the string first, then turn the string into Data, then decode that Data again:
// nil handling omitted for brevity
let jsonString = try! JSONDecoder().decode(String.self, from: data)
let jsonData = jsonString.data(using: .utf8)!
let sub = try! JSONDecoder().decode([Subsidiary].self, from: jsonData)
Of course, the best solution is to fix the backend.

How to post array of single value in alamofire?

I have to post json object.
One important thing, I have to post array of single value.
look at below code.
var pagingOption: [String: Any] = ["page": page,
"rowsPerPage": 20,
"sort": ["id": sortOption.rawValue,
"direction": "DESC"],
"searchStatues": ["accept"]]
searchStatuses is must array. But If I send this code, searchStatuses is not posted array.
If I add more value like this
var pagingOption: [String: Any] = ["page": page,
"rowsPerPage": 20,
"sort": ["id": sortOption.rawValue,
"direction": "DESC"],
"searchStatues": ["accept", "asdf", "asdf"]]
Then delivered array.
If I have only single value, How can I do that??
You can do it this way.
let searchValues: [String] = []
searchValues = ["accept", "asdf", "asdf"]
var pagingOption: [String: Any] = ["page": page,
"rowsPerPage": 20,
"sort": ["id": sortOption.rawValue,
"direction": "DESC"],
"searchStatues": searchValues]

Swift Cannot append to subscript on type JSON

I'm getting JSON data using SwiftyJSON, and got a changeable array using:
let worldDataGenJSON = JSON(data:data)
worldDataGenBlocks = worldDataGenJSON["blocks"]["x"].arrayValue as Array
With this, I can append to worldDataGenBlocks easily like:
worldDataGenBlocks.append([
"y": [:]
])
I created a new array inside worldDataGenBlocks called "y", but I'm not able to append to it
worldDataGenBlocks[0]["y"][0].append([
"bid": 0,
"id": 0,
"fid": 0
])
It would say:
Value of type 'JSON' has no member 'append'
I tried to set it this way too, but with no avail:
worldDataGenBlocks[cX]["y"][cY] = [
"bid": 0,
"id": 0,
"fid": 0
]
Every time I print "worldDataGenBlocks" it would show empty "y" arrays.
Please help.

POST multiple json objects in Alamofire POST method - Swift/IOS

Sorry if my question is not clear, I'll try to make myself clear with an explanation. So here is exactly what I'm trying to do, I'm trying to use Alamofire to post more than one comment (Something that my app implements and will be stored as a JSON object whenever user writes a new comment). I'm passing these JSON comments to my post routine, where I can use SwiftyJSON to extract each value. Noe the thing is I know how to set the parameters if I'm trying to authorize the user as follows,
var parameters = [
"userName": userName,
"password": passwordSalt,
"somethingElse": somethingElse
]
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters , options: nil, error: &err)
it's quite straightforward until here, now comes my problem. I'm trying to use alamofire post to post multiple json objects, which should look like this
[
{
"comment": "my First Comment",
"commentDate": "2014-05-13 14:30 PM",
"isSigned": 1,
"patientId": 2,
"documentId": 3
},
{
"comment": "my SecondComment",
"commentDate": "2014-05-14 14:30 PM",
"isSigned": 2,
"patientId": 3,
"documentId": 4
},
{
"comment": "my third Comment",
"commentDate": "2014-05-15 14:30 PM",
"isSigned": 3,
"patientId": 4,
"documentId": 5
}
]
How do I create above array/json (I'm not exactly sure on what to call this) by iterating JSON object? I know how to get the JSON values from the JSON object all I'm asking is how to create this parameters variable to hold the data like above example. Is it even possible to do this using Alamofire? (POST multiple objects at once)
I tried a couple of ways to but they didn't work out
var dictArray = [Dictionary<String, Any>]
var dict = Dictionary<String, Any>
While iterating over JSON object inserted each value in dict and appended dict to dictArray, now when I'm trying to use dictArray as parameters in .dataWithJSONObject it doesn't like the object.
var dict = Dictionary<String, AnyObject>
var array = NSArray()
extracted each value by iterating over the JSON object and inserted them into dict and tried inserting dict into array. But this gives a different problem. The way it builds the objects is different from what is required, as follows.
[
{
comment: my First Comment,
commentDate: 2015-05-13 13:30 PM"",
isSigned: 1,
patientId: 2,
documentId: 3
},
{
comment: my Second Comment,
commentDate: 2015-05-13 13:30 PM"",
isSigned: 2,
patientId: 5,
documentId: 4
},
{
comment: my third Comment,
commentDate: 2015-06-13 13:30 PM"",
isSigned: 5,
patientId: 1,
documentId: 9
}
]
Here the Keys doesn't get wrapped inside quotes (Correct way: "comment", wrong way: comment).
Did anyone try posting multiple objects, is alamofire capable of doing so? I hope I made the question clear. Sorry if this is too simple of a question to answer, I spent my whole day figuring this out but didn't work out.
The correct representation in Swift for the array of comment objects you have posted would be like this:
let comments: Array<[String:AnyObject]> = [
[
"comment": "my First Comment",
"commentDate": "2014-05-13 14:30 PM",
"isSigned": 1,
"patientId": 2,
"documentId": 3
],
[
"comment": "my SecondComment",
"commentDate": "2014-05-14 14:30 PM",
"isSigned": 2,
"patientId": 3,
"documentId": 4
],
[
"comment": "my third Comment",
"commentDate": "2014-05-15 14:30 PM",
"isSigned": 3,
"patientId": 4,
"documentId": 5
]
]
Sending a single comment would be fairly simple:
let comment: [String:AnyObject] = [
"comment": "my First Comment",
"commentDate": "2014-05-13 14:30 PM",
"isSigned": 1,
"patientId": 2,
"documentId": 3
]
Alamofire.request(.POST, "http://httpbin.org/post", parameters: comment).responseJSON { (req, res, json, error) in
println(req)
println(res)
println(json)
println(error)
}
However, in order to send an array of comments, seems like you would have to generate the URLRequest your self and then pass it to Alamofire as follows:
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "http://httpbin.org/post")!)
mutableURLRequest.HTTPMethod = "POST"
var error: NSError? = nil
let options = NSJSONWritingOptions.allZeros
if let data = NSJSONSerialization.dataWithJSONObject(comments, options: options, error: &error) {
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.HTTPBody = data
}
Alamofire.request(mutableURLRequest).responseJSON { (req, res, json, error) in
println(req)
println(res)
println(json)
println(error)
}
If you could modify the API backend to accept an object with multiple comments, you could also send them this way:
Alamofire.request(.POST, "http://httpbin.org/post", parameters: ["comments": comments]).responseJSON { (req, res, json, error) in
println(req)
println(res)
println(json)
println(error)
}
Regards.
This would be better
Create dictionary and array of dictionary var
Then loop how many parameters you need to send from data source either an array or whatever.
Here my scenario
Need to answer to all questions (will be a random number/size)
var ansParams = [[String: String]]()
var paramz = [String: String]()
for question in sectionQuestions{
paramz = [
AppConstants.PARAMETER.KEY_1 : "Value",
AppConstants.PARAMETER.KEY_2 : "Value",
AppConstants.PARAMETER.KEY_3 : "Value",
AppConstants.PARAMETER.KEY_4 : "Value",
AppConstants.PARAMETER.KEY_5 : "Value"
]
ansParams.append(paramz)
}
print(ansParams)
//Check All Paramz and its values then send ansParams as Parameter to POST request
I had a similar issue in my project while working with an API that did now allow posting multiple objects at once. The formatting of the array as noted above is fine.
let comments: Array<[String:AnyObject]> = [
[
"comment": "my First Comment",
"commentDate": "2014-05-13 14:30 PM",
"isSigned": 1,
"patientId": 2,
"documentId": 3
],
[
"comment": "my SecondComment",
"commentDate": "2014-05-14 14:30 PM",
"isSigned": 2,
"patientId": 3,
"documentId": 4
],
[
"comment": "my third Comment",
"commentDate": "2014-05-15 14:30 PM",
"isSigned": 3,
"patientId": 4,
"documentId": 5
]
]
Then I used a for loop to post each object of the array to post the API.
var index = comments.count
var i = 0
for i = 0; i < index; i++ {
let urlString = "\(.baseURL)...etc"
let parameters = comments[i]
Alamofire.request(.POST, urlString, parameters: parameters)
.responseJSON { (req, res, data, error) -> Void in
// println(req)
// println(res)
// println(data)
// println(error)
println("\(i) of \(index) posted")
}
}
More efficient ways if the API allows, but otherwise this flow works great.

Parser to json JSON array using swift

I am doing an IOS (swift) app that communicates with a server.
Response from server is a JSON array which contains some JSON objects.
When i show by console string response is fine:
[{"NAME":"","SURNAME":"","ID":5,"USERNAME":"dpcabo2"},{"NAME":"","SURNAME":"","ID":10,"USERNAME":"default"},{"NAME":"","SURNAME":"","ID":11,"USERNAME":"esteban"}]
But when i try parser this info to json using this:
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(self.my_data!,
options:NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("\(jsonResult)")
app crashes.
So i need a solution to parser correctly this information.
Ps.self.my_data! is a NSMutableData.
Thanks
You can use below code for parsing. It prints and parse you object properly.
import Foundation
let jsonObject: [AnyObject] = [
["NAME":"","SURNAME":"","ID":5,"USERNAME":"dpcabo2"],
["NAME":"","SURNAME":"","ID":10,"USERNAME":"default"],
["NAME":"","SURNAME":"","ID":11,"USERNAME":"esteban"]
]
let jsonOptional: AnyObject! = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions(0), error: nil)
Response is as below:
[["USERNAME": "dpcabo2", "ID": 5, "NAME": "", "SURNAME": ""],
["USERNAME": "default", "ID": 10, "NAME": "", "SURNAME": ""],
["USERNAME": "esteban", "ID": 11, "NAME": "", "SURNAME": ""]]

Resources