Swift Use array in Json [duplicate] - arrays

This question already has an answer here:
JSON with "(" ")" brackets istead of "[" "]" [closed]
(1 answer)
Closed 5 years ago.
When I add an array in my JSON object and convert it to JSON, after printing there is parenthesis instead of curly brace.
var jsonObject : [String: Any] = [:]
var x = [1,2,3,4]
jsonObject["arr"] = x
do{
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
print(decoded)
} ...
And the result of printing:
{
arr = (
1,
2,
3,
4
);
}
But in JSON, to show an array it uses [ instead of (.
What's wrong?

You are converting the dictionary(!) to JSON and then you convert it back and print it.
To print the JSON string you have to write
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject)
let jsonString = String(data: jsonData, encoding: .utf8)
print(jsonString ?? "Wrong data")

When you print a Swift object, Swift debugger is free to print it however it wants. It's just for convenience, there are no guarantees about the format. So, it prints arrays in parenthesis.
When you convert it to JSON, on the other hand, it creates a JSON string, and JSON has a specified format for arrays, which includes square brackets.
UPDATE: after reading the question again, it seems to me you're under the impression that you're printing a JSON representation of your object. You're not. What you do currently is you convert your Swift object to JSON, and then convert it back to a Swift object. And then you print the resulting Swift object (see paragraph 1 of my answer).
So, if your goal is to print the JSON representation, you need to convert jsonData to String (see other answers), and print that string. You shouldn't use NSJSONSerialization again for backward conversion.

You should use this to print your JSON.
public extension Collection {
/// Convert self to JSON String.
/// - Returns: Returns the JSON as String or empty string if error while parsing.
func json() -> String {
do {
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
guard let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) else {
print("Error creating string with data.")
return "{}"
}
return jsonString
} catch let parseError {
print("json serialization error: \(parseError)")
return "{}"
}
}
}
The conversion is correct, It's just that you are printing decoded version, which is swift dictionary, not JSON.
var jsonObject : [String: Any] = [:]
var x = [1,2,3,4]
jsonObject["arr"] = x
print(jsonObject.json())
do{
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
print(decoded)
}
Output:-
{
"arr" : [
1,
2,
3,
4
]
}

I added some print clauses to you code, and pasted the console log as comments.
var jsonObject : [String: Any] = [:]
var x = [1,2,3,4]
jsonObject["arr"] = x
print(type(of: jsonObject)) // Dictionary<String, Any>
do{
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments)
print(type(of: decoded)) // __NSSingleEntryDictionaryI
let str = String(data: jsonData, encoding: .utf8)
print(str!) /* {
"arr" : [
1,
2,
3,
4
]
}*/
}
As you can see, the type of decoded is __NSSingleEntryDictionaryI, so its result of printing is not as what you expected, with "(" instead of "[". If you want the right representation in JSON, you should convert the jsonData to String.

Related

How can I convert an array to string in swift?

I want to convert an array to string like this
let myArray:[Any] = ["element 1", "element 2", ["element 3.1", "element 3.2"], "element 4"]
to
let convertedString = "[\"element 1\",\"element 2\",\"[\\\"element 3.1\\\",\\\"element 3.2\\\"]\",\"element 4\"]"
I have tried this
do {
let jsonData: Data = try JSONSerialization.data(withJSONObject: myArray, options: [])
if let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue) {
print(jsonString)
}
} catch let error as NSError {
print("Array convertIntoJSON - \(error.description)")
}
However I get this result
["element 1","element 2",["element 3.1","element 3.2"],"element 4"]
I have done this in java by using JSONArray. I just call toString method to do this in java. I need to get third element as a string like given example above.
This should do:
"\(myArray.map { "\($0)" })"

Convert Swift 3 Array to JSON

I have array of dictionary [[String:Any]] i want to convert it to JSON string. but i don't know how to start with it. I tried JSONSerialization.data(withJSONObject: array, options: .prettyPrinted) and i pass array to method but it show error. Any solution please comment below. Thank.
Try as following code...
do {
//Convert to Data
let jsonData = try JSONSerialization.data(withJSONObject: dictionaryArray, options: JSONSerialization.WritingOptions.prettyPrinted)
//Do this for print data only otherwise skip
if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {
print(JSONString)
}
//In production, you usually want to try and cast as the root data structure. Here we are casting as a dictionary. If the root object is an array cast as [AnyObject].
var json = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: AnyObject]
} catch {
print(error.description)
}

How we can find an element from [AnyObject] type array in swift

I have [AnyObject] array
var updatedPos = [AnyObject]()
I am setting data in that according to my requirement like!
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue(posId, forKey: "id")
para.setValue(posName, forKey: "job")
let jsonData = try! NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
self.updatedPos.append(jsonString)
Now in my code i have some requirement to remove the object from this array where id getting matched according to requirement Here is the code which i am trying to implement
for var i = 0; i < updatedPos.count; i++
{
let posItem = updatedPos[i]
print("Id=\(posItem)")
let pId = posItem["id"] as? String
print("secRId=\(pId)")
if removeId! == pId!
{
updatedPos.removeAtIndex(i)
}
}
Here print("Id=\(posItem)") give me output asId={"id":"51","job":"Programmer"} but here i am not able to access id from this object. here print("secRId=\(pId)") give me nil
First of all use native Swift collection types.
Second of all use types as specific as possible.
For example your [AnyObject] array can be also declared as an array of dictionaries [[String:AnyObject]]
var updatedPos = [[String:AnyObject]]()
Now create the dictionaries and add them to the array (in your example the dictionary is actually [String:String] but I keep the AnyObject values).
let para1 : [String:AnyObject] = ["id" : "51", "job" : "Programmer"]
let para2 : [String:AnyObject] = ["id" : "12", "job" : "Designer"]
updatedPos.append(para1)
updatedPos.append(para2)
If you want to remove an item by id use the filter function
let removeId = "12"
updatedPos = updatedPos.filter { $0["id"] as? String != removeId }
or alternatively
if let indexToDelete = updatedPos.indexOf{ $0["id"] as? String == removeId} {
updatedPos.removeAtIndex(indexToDelete)
}
The JSON serialization is not needed for the code you provided.
PS: Never write valueForKey: and setValue:forKey: unless you know exactly what it's doing.
After some little bit stuffs I have found the very easy and best solution for my question. And I want to do special thanks to #vadian. Because he teach me new thing here. Hey Thank you very much #vadian
Finally the answer is I had covert posItem in json Format for finding the id from Id={"id":"51","job":"Programmer"} this string
And the way is
let data = posItem.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
if let dict = json as? [String: AnyObject] {
let id = dict["id"]
if removeId! == id! as! String
{
updatedLoc.removeAtIndex(i)
}
}
}
catch {
print(error)
}

JSON To Array in Swift

I'm Using Swift2.0+, SwiftyJSON, Alamofire
I Got the Value let stringJSON:JSON = ["a1","a2","a3"] from Server
But If I Check stringJSON[0],Then it's null
When I debugPrint(stringJSON), Then it's ["a1","a2","a3"]
How Can I got the value stringJSON[0] //"a1" ?
Do I Have To Convert From JSON To Another?
The correct syntax is
let stringJSON:JSON = ["a1","a2","a3"]
if let firstValue = stringJSON.array?.first {
print(firstValue) // a1
}
Update
Since the value actually contains this string "[\"a1\/a1\",\"a2\/a2\",\"a3\"]" and you cannot fix this on the server side here it is a workaround.
if let words = stringJSON.string?.characters.dropFirst().dropLast().split(",").map(String.init) {
let word = String(words[0].characters.dropFirst().dropLast())
print(word) // a1
}
if let x = stringJSON[0].string{
print(x)
}
Since the server is not returning an Array, but a String, you need to convert that into an Array of Strings like this:
let string = stringJSON.string
let array = string.stringByReplacingOccurrencesOfString("[", withString: "")
.stringByReplacingOccurrencesOfString("]", withString: "")
.stringByReplacingOccurrencesOfString("\"", withString: "")
.componentsSeparatedByString(",")
stringJSONIf it is a string type, you can like this to solve:
extension String {
var parseJSONString: AnyObject? {
var any: AnyObject?
let data = self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
do{
any = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)
}catch let error as NSError{
print("error: \(error)")
}
return any
}
and use it like this:
let strArr = stringJSON.stringvalue.parseJSONString as! Array<String>

Compiling Swift source files hangs on large array reduce-combine + expressions

In my tests I'm used to write Strings in arrays in different lines like
let jsonString = ["{"
,"\"url\": \"http://localhost:8090/rest/api/3\","
, "\"id\": \"3\","
, "\"description\": \"A test that needs to be done.\","
, "\"name\": \"Test\","
, "\"subtest\": false,"
, "\"avatar\": 1"
,"}"].reduce("", combine: +)
That works fine, still my array get 145 lines for a large test json string.
With 145 lines (or maybe less, didn't tried it line by line) the build task hangs while "Compiling Swift source files".
First, that is a bit crazy. 30 lines are ok, 145 not? What?
Second, what is a better solution to write a String in multiple lines in Swift? - I don't want to load a json and parse it from an external file.
This is probably because of type inference.
Try giving an explicit [String] type to an array variable to help the compiler figure it out, then apply reduce to the variable.
let arrayOfStrings: [String] = ["{"
,"\"url\": \"http://localhost:8090/rest/api/3\","
, "\"id\": \"3\","
, "\"description\": \"A test that needs to be done.\","
, "\"name\": \"Test\","
, "\"subtest\": false,"
, "\"avatar\": 1"
,"}"] // etc
let jsonString = arrayOfStrings.reduce("", combine: +)
Anyway, to create JSON you should make a dictionary then serialize it with NSJSONSerialization, this is less error prone:
Swift 2
do {
// Create a dictionary.
let dict = ["url": "http://localhost:8090/rest/api/3", "id": "3"] // etc
// Encode it to JSON data.
let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: [])
// Get the object back.
if let jsonObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as? [String:String] {
print(jsonObject)
}
// Get it as a String.
if let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding) {
print(jsonString)
}
} catch let error as NSError {
print(error)
}
Swift 3
do {
// Create a dictionary.
let dict = ["url": "http://localhost:8090/rest/api/3", "id": "3"] // etc
// Encode it to JSON data.
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
// Get the object back.
if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String:String] {
print(jsonObject)
}
// Get it as a String.
if let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) {
print(jsonString)
}
} catch let error as NSError {
print(error)
}

Resources