Accessing JSON data using Swift - swift

I am trying to access a key from the following JSON:
{ items = ({a = “string for a”;b = “string for a”;c = “string for a”;},{a = “string for a”;b = “string for a”;c = “string for a”;},{a = “string for a”;b = “string for a”;c = “string for a”;});}
For example, I would like to get the value for the first key 'a', but the following returns nil:
println(jsonResult["products[product_id]"]

Your JSON Example is not valid. Check out with this:
http://jsoneditoronline.org/
I would use a common JSON Plugin for Swift. For Example this:
https://github.com/owensd/json-swift
And then use:
let json : JSON = "your string"
And get your objects with:
if let myproduct = json["products"]["productid"].array {
// content of your product (if array)
}

Related

Swift - Core Data - using the result of fetch with GroupBy

I couldn't find answer to this question, I checked all questions here.
Summary:
I don't know how to use the result(that I successfully get back) of .fetch() method with GroupBy. The fetch method result must have .dictionaryResultType because I am using GroupBy, otherwise the GroupBy would not work. I can see that fetch returns [Any], so array of Any. However I try to cast/use/access this [Any] it fails.
My code:
//Create new entity
let timeLogEntity = NSEntityDescription.entity(forEntityName: "TimeLog", in: managedContext)!
//sum up the duration column
let keypathDuration = NSExpression(forKeyPath: "duration")
let expression = NSExpression(forFunction: "sum:", arguments: [keypathDuration])
let sumDesc = NSExpressionDescription()
sumDesc.expression = expression
sumDesc.name = "DurationSum"
sumDesc.expressionResultType = .integer64AttributeType
//Fetch request
var timeLogFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "TimeLog")
//group by region
timeLogFetchRequest.returnsObjectsAsFaults = false
timeLogFetchRequest.propertiesToGroupBy = ["region"]
//sum of duration column
timeLogFetchRequest.propertiesToFetch = [sumDesc, "region"]
timeLogFetchRequest.resultType = .dictionaryResultType
//it works only like this with [Any[\]
var dailyFetchResult: [Any]?
do{
dailyFetchResult = try managedContext.fetch(timeLogFetchRequest)
}catch...
So the fetch works and returns values, I just don't know how to use them, or convert them to anything usable dictionary, tuple, String and Int...
The result looks like this: {DurationSum = 235; region = RegionName1}{DurationSum = 256; region = RegionName2} etc
Thanks
(dailyFetchResult[0] as! [String:Any]).keys , and (dailyFetchResult[0] as! [String:Any]).values did it. Thank you!

Use SwiftyJSON to get proper data

This is my JSON data, how can I get src data in 0 in pickArray?
"pickArray" : "{\"0\":{\"src\":\"https:\/\/fb-s-d-a.akamaihd.net\/h-ak-xpl1\/v\/t1.0-9\/p720x720\/18010403_1525007564199498_8009700960533638318_n.png?oh=25dbc9c1522dcfdd1d15cdd3e8c0c7da&oe=59997685&__gda__=1502470695_f212ade003e9b1c4ddc6a3ab6cc9e7e7\",\"width\":720,\"height\":720}}"
If I do it like this:
let dataArray = json["pickArray"]
print("dataArray = ",dataArray)
dataArray = {"0":{"src":"https://fb-s-d-a.akamaihd.net/h-ak-xpl1/v/t1.0-9/p720x720/18010403_1525007564199498_8009700960533638318_n.png?oh=25dbc9c1522dcfdd1d15cdd3e8c0c7da&oe=59997685&__gda__=1502470695_f212ade003e9b1c4ddc6a3ab6cc9e7e7","width":720,"height":720}}
But if I do it like this, show null:
let srcArray = dataArray["0"]
print("srcArray = ",srcArray)
I'm using swift3.0
Its looks like that with key pickArray you are having JSON response in String so get that string and convert it data and get JSON from it and then get src from it.
let stringResponse = json["pickArray"].stringValue
if let data = stringResponse.data(using: .utf8) {
let pickArray = JSON(data: data)
//Now access the pickArray to get the src
var sortedKeys = [String]()
if let allKeys = pickArray.dictionaryObject {
sortedKeys = Array(allKeys.keys).sorted { $0.compare($1, options: .numeric) == .orderedAscending }
}
for key in sortedKeys {
print(pickArray[key]["src"].stringValue)
print(pickArray[key]["width"].intValue)
print(pickArray[key]["height"].intValue)
}
}
let srcArray = dataArray["0"].dictionaryObject!
print("srcArray = \(srcArray)")
Now you can access element of "0" value as like below. Hope this work for you.
let jsonScr = JSON(srcArray)
let srcURL = jsonScr["scr"].stringValue

How to identify the type of an object?

Here is my JSON response for a particular API.
Case 1
ChallengeConfiguration = {
AnswerAttemptsAllowed = 0;
ApplicantChallengeId = 872934636;
ApplicantId = 30320480;
CorrectAnswersNeeded = 0;
MultiChoiceQuestion = (
{
FullQuestionText = "From the following list, select one of your current or previous employers.";
QuestionId = 35666244;
SequenceNumber = 1;
},
{
FullQuestionText = "What color is/was your 2010 Pontiac Grand Prix?";
QuestionId = 35666246;
SequenceNumber = 2;
}
)
}
The key "MultiChoiceQuestion" returns an array with two questions. So here is my code.
let QuestionArray:NSArray = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as! NSArray
Case 2
ChallengeConfiguration =
{
AnswerAttemptsAllowed = 0;
ApplicantChallengeId = 872934636;
ApplicantId = 30320480;
CorrectAnswersNeeded = 0;
MultiChoiceQuestion = {
FullQuestionText = "From the following list, select one of your
current or previous employers.";
QuestionId = 35666244;
SequenceNumber = 1;
}
}
For Case 2 my code does not work and app crashes because it returns a dictionary for that specific Key. So how could I write a generic code that would work for all objects?
It looks like the key can contain either an array of dictionary values or a dictionary, so you just need to try casting to see which one you have.
so I would likely do it like this:
if let arr = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as? Array {
// parse multiple items as an array
} else if let arr = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as? [String:AnyObject] {
// parse single item from dictionary
}
You should never really use ! to force unwrap something unless you are completely certain that the value exists and is of the type you are expecting.
Use conditional logic here to test the response and parse it safely so that your app doesn't crash, even in failure.

Swift 3: Iterate through a _NSSingleObjectArrayI

I'm fetching data from a weather API. I'm not sure how to access the description?
"weather": <__NSSingleObjectArrayI 0x608000012910>(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
I tried:
print(weatherDict["weather"]!.description!)
It just gave me this:
(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
How do I properly access the description?
weather contains an array of dictionaries.
description is a key in the first item of the array.
The code unwraps weather safely and checks if the array is not empty:
if let weatherArray = weatherDict["weather"] as? [[String:Any]],
let weather = weatherArray.first {
print(weather["description"]) // the value is an optional.
}

Multidimensional array makes Xcode6 crash

I have an application which retrieves a JSON file. Here you are a piece of my code:
Array definition
var photos: NSArray = []
How I populate the array:
ezJson().createRequest("http://myapiurl/load", type: "GET", params: nil, completion: {(returnedObject : AnyObject?, error : NSError?)in
if returnedObject{
self.photos = returnedObject as NSArray
self.tableView.reloadData()
}
})
println(self.photos)
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
},
{
created = {
date = "2014-06-13 18:38:38";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description2;
id = 4;
name = 539b290ed8577;
}
println(self.photos[0])
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
}
The problem is, I don't know how to get a particular item. I've tried:
println(self.photos[0]) // it works
println(self.photos[0]["name"] // Xcode crash "Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254"
println(self.photos[0].name) // returns nil
How can I access to the name parameter ?
It seems that you are casting a String to NSArray. This won't give you the effect that you want.
First of all, if you want to acces your elements by name, you want an NSDictionary.
Then it propably still won't work, as there is no implicit conversion between the types so you will have to either parse it yourself or use some JSON library.
Last : your JSON is incorrect.