How to reform JSON in swift? - ios

I am working on JSON in iOS swift,
I will query data from server as,
results = [{"type":"fruit", "name":"orange"},
{"type":"flower", "name":"rose"},
{"type":"fruit", "name":"apple"}]
I need to append above data to TableView based on the type, so that it will be displayed as shown below,
fruit
orange
apple
flower
rose
In order to display in TableView, the results should reform as,
updatedResult[String:[AnyObject]]() = {
"fruit":[{"name":"orange"},{"name":"apple"}],
"flower":[{"name":"rose"}]
}
How is it possible to reform the results to updatedResult using swift?

//Your example json
results = [{"type":"fruit", "name":"orange"},{"type":"flower","name":"rose"},{"type":"fruit", "name":"apple"}]
First you need to turn your json into an array of dictionaries to get the above object you think it will be:
if let results = try NSJSONSerialization.JSONObjectWithData(data,options: NSJSONReadingOptions.MutableContainers) as? [[String : AnyObject]]
{ //parse into form you want.}
// Your example desired result of dictionary with key:array of dictionaries
updatedResult[String:[AnyObject]]() = {"fruit":[{"name":"orange"},{"name":"apple"}],"flower":[{"name":"rose"}]}
Then you want to loop through the json result and grab out the values into the above format you want:
// Swift representation of your provided example
let results = [["type":"fruit", "name":"orange"],["type":"flower","name":"rose"],["type":"fruit", "name":"apple"]]
// Desired dictionary of key:array of dictionaries
var updatedResult = [String:[[String:String]]]()
for item in results {
if let name = item["name"], type = item["type"] {
if updatedResult.keys.contains(type) {
updatedResult[type]!.append(["name":name])
} else {
updatedResult[type] = [["name":name]]
}
}
}

Related

I have and array inside the value of dictionary

I have an dictionary and the value containts the array of string as follows
arr = ["key":"["a","b","c","d","e","f","g"]"]
I want the new array to be like
let array = ["a","b","c","d","e","f","g"]
How to parse it
You can access dictionary items in few different ways, the easiest is:
let array = arr["key"]
You may need to conditionally unwrap it
if let array = arr["key"] as? [String] {
// rest of code with array
}

NSFastEnumerationIteration.member Swift 3

I have some difficult to convert my Swift 2.2 app to Swift 3.0.
I have some errors and I don't find the solution yet. Currently, my worst problem is with NSFastEnumerationIteration, I try to get records from JSON but with this error I can't. This is the screenshot of my code with the problem :
In Swift 3 you need to specify the type of object,so specify the type of your data Array to [[String:Any]].
if let dataArr = data as? [[String: Any]] {
for dd in dataArr {
//your code for accessing dd.
}
}
For in loop only knows that your variable data is an array and doesn't know anything else, so you need to provide as well the type of the content of your variable data:
let dataToParse = dataweneed.data(using: String.Encoding.utf8.rawValue)!
let jsonOptions = [JSONSerialization.ReadingOptions.mutableContainers]
let data = try JSONSerialization.jsonObject(with: dataToParse, options: jsonOptions)
// now For in loop would know that you
// could have an array of dictionaries
if let data = data as? [[String: Any]] {
for dd in data {
// your code
}
}

Getting value from json response Swift

[{
"_text" = "turn off the air con";
confidence = "0.609";
entities = {
"on_off" = (
{
value = off;
}
);
};
intent = "aircond_temperature";
}]
I have a json response named "outcomes", and I would like to extract the "off" value from "on_off".
So far what I've done is to get the first element from the response and then cast it to an NSDictionary which works fine, and then using object for key to get the values of each dictionary, and casting them to their respective types.
let firstOutcome:NSDictionary = outcomes.first as! NSDictionary
let intent:String = firstOutcome.objectForKey("intent") as! String
let entities:NSDictionary = firstOutcome.objectForKey("entities") as! NSDictionary
But when it comes to entities I have no idea what type should I cast "on_off" to. Any ideas?
your "on_off" key contain array of dictionaries, so you could try to access it by using this code.
let entities:NSDictionary = firstOutcome.objectForKey("entities") as! NSDictionary
let onOff = entities["on_off"] as! NSArray
let firstValue = onOff.firstObject as! NSDictionary
print(firstValue["value"])
The brackets tell the whole story. { is an object or dictionary, ( is an array. So, entities is a dictionary containing an array of dictionaries, where the inner dictionary has string keys and values.
Try this code:
let entities = entities["on_off"]
for var entity in entities {
print_r(entity["value"])
}

iOS 9 JSON Parsing loop

I'm creating an app that should retrieve some JSON from a database.
This is how my JSON looks:
[{"id":"1","longitude":"10","latitude":"10","visibility":"5","timestampAdded":"2015-10-01 15:01:39"},{"id":"2","longitude":"15","latitude":"15","visibility":"5","timestampAdded":"2015-10-01 15:06:25"}]
And this is the code i use:
if let jsonResult = JSON as? Array<Dictionary<String,String>> {
let longitudeValue = jsonResult[0]["longitude"]
let latitudeValue = jsonResult[0]["latitude"]
let visibilityValue = jsonResult[0]["visibility"]
print(longitudeValue!)
print(latitudeValue!)
print(visibilityValue!)
}
As you can see it only gets the first chunk from the JSON and if there are no JSON at all it will crash, but if i want it to count the amount and make an array out of it like this:
var longitudeArray = [10, 15]
var latitudeArray = [10, 15]
And so on...
I also need this to be apple watch compatible so i can't use SwiftyJSON.
What do i do? I really hope you can help me!
Thanks.
SOLVED!
Problems was solved by "Eric D."
This is the code:
do {
if let url = NSURL(string: "YOU URL HERE"),
let data = NSData(contentsOfURL: url),
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] {
print(jsonResult)
let longitudeArray = jsonResult.flatMap { $0["longitude"] as? String }
let latitudeArray = jsonResult.flatMap { $0["latitude"] as? String }
print(longitudeArray)
print(latitudeArray)
}
} catch let error as NSError {
print(error.description)
}
Thank you soo much Eric!! :-)
You could use flatMap to get an array of your elements:
let longitudeArray = jsonResult.flatMap { $0["longitude"] as? String }
let latitudeArray = jsonResult.flatMap { $0["latitude"] as? String }
etc.
flatMap is like map but unwraps optionals, which is adequate because we need to safely cast the type of the object we get from each dictionary in the json array.
$0 represents the object in the current iteration of flatMap of the array it's applied to.
If you're currently using SwiftyJSON, then that would be:
let longitudeArray = jsonResult.flatMap { $1["longitude"].string }
let latitudeArray = jsonResult.flatMap { $1["latitude"].string }
because .string is SwiftyJSON's optional String value getter.
But as you said, you don't want to use it (anymore), so you need to use NSJSONSerialization to decode your JSON data, there's plenty of examples on the Web and on SO. Then you will be able to use my original answer.
You're already getting an array with all of the elements (not just the first one. you're simply only accessing the first one). jsonResult is an array of dictionaries. Each dictionary (in this case, based on the json you provided) contains these elements: id, longitude, latitude, visibility and timestampAdded. In order to access each of them, you can simply loop over jsonResult and access the i'th element (and not always the 0 element). This will also prevent the crash you're experiencing with the json is blank or invalid (since you'll only be going over the valid elements in jsonResult.
This will give you the flexibility to create the custom arrays you wish to create (in order to create an array of all of the longitudes, for example, you will simply add that element to the new array while looping over jsonResult). However, if you'd like to save yourself the trouble of manually building these arrays and assuming you have control over the json structure, I would recommend changing the received json to the relevant structure (a dictionary or arrays instead of an array of dictionaries), so it would better fit your needs and provide you the results in the relevant format right "out of the box".

iOS, Swift - JSON Response. VK SDK

I am using the VK SDK for iOS, and I need to take out the images URLs from JSON response from VK.
The response is look like this:
The actual response could be AnyObject OR String, and I only need the largest image URL (photo_1280) as string.
In the response comes 1-10 photos and which parameters I will need to change to get the particular photo like first or second and so on.
I'm using Swift in my project but can understand Objective-C.
JSON is just a format that lets you exchange information between languages (or objects).
You need to 'parse' the string into a JSON object. Its a little different for each language. For example on iOS I create my UI elements from a JSON file where I load the file and create a dictionary object from it. In your case you are doing it from a string. You need to turn that string into a valid object in your language. In Swift I prefer a Dictionary. So I use a typealias for that and cast the nsDictionary as that type of object.
Then to access objects, I access keys in the dictionary. In your case you would create a dictionary object too, and access the "attachments" object, which in your case is an array so you'll need to do extra processing on it to get each image (i.e. go through the array). This should get you going.
typealias Dict = Dictionary<String,AnyObject>
func loadDictionaryFromJSON(jsonString:String) -> Dict
{
var JSONData:NSData! = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
var JSONError:NSError?
let swiftObject:AnyObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions.AllowFragments, error: &JSONError)!
if let nsDictionaryObject = swiftObject as? NSDictionary
{
if let dictionaryObject = nsDictionaryObject as Dictionary?
{
return dictionaryObject as Dict
}else
{
println("Error could not make dictionary from NSDictionary in \(self)")
}
}else
{
"Error could not make NSDictionary in \(self)"
}
println("Empty dictionary passed, fix it!")
return Dict()
}
Now to access things you just do
var objects:Dictionary<String,AnyObject> = loadDictionaryFromJSON("{"what":"ever"}")
var whatever = objects["what"]

Resources