Swift: Create Dictionary from Inner Items of JSON Array - json

In Swift, I have a POST request to a URL which returns JSON similar to this:
{"users":[{
"user":{"userID":"1","userName":"John"}},
{"user":{"userID":"2","userName":"Mary"}},
{"user":{"userID":"3","userName":"Steve"}},
]}
Here's the Swift code:
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
println(result?.count)
println(result)
...Which outputs this:
Optional(1)
Optional({
users = ({
user = {
userID = 1;
userName = John;
};
},
{
user = {
userID = 2;
userName = Mary;
};
},
{
user = {
userID = 3;
userName = "Steve";
};
});
})
I'm trying to loop through the "user" elements but nothing I try is working. I have a dictionary of the "user" level JSON, but don't know how to go on to get the child "users" of this. Does anyone know how I can do this? If I could look through them to println() the users' names that would be a great start.

Try this.
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
if let users = result?.objectForKey("users") as? [[String:AnyObject]]
{
for user in users
{
if let userValues = user["user"] as? [String:AnyObject]
{
println(userValues["userID"]!)
println(userValues["userName"]!)
}
}
}

Related

Accessing JSON data with Swift

I have an array of JSON data from the following call:
guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [Any] else {
print("Not containing JSON")
return
}
when I run print(json) I get the following in the output:
[{
"CREATED_BY" = "DOMAIN\\USER";
"CREATED_DATE" = "2016-11-28T08:43:59";
STATUS = U;
"WIDGET_NUMBER" = K11;
"UPDATED_BY" = "<null>";
"UPDATED_DATE" = "<null>";
}, {
"CREATED_BY" = "DOMAIN\\USER";
"CREATED_DATE" = "2016-05-09T08:46:23";
STATUS = U;
"WIDGET_NUMBER" = 89704;
"UPDATED_BY" = "<null>";
"UPDATED_DATE" = "<null>";
}]
I am trying to get all of the WIDGETNUMBER values in the array of JSON data. The json variable is a Any type and I have not been able to convert to a struct so far. Is there an easy way to get the elements from the JSON objects?
It looks like you have an array of dictionaries
for item in json {
if let item = item as? [String: Any], let widgetNo = item["WIDGET_NUMBER"] {
print(widgetNo)
}
}
Your content is array of Dictionary, so that you must convert each element Dictionary to Json
for dic in content {
do {
let jsonData = try JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
print(jsonData)
} catch {
print(error.localizedDescription)
}
}
Or you can read value of WIDGET_NUMBER direct from Dictionary
for dic in content {
print(dic["WIDGET_NUMBER"] ?? "Not found")
}
Joakim's answer is spot on for getting the widget number. For your struct, be sure to add something like this as an initializer to map your object.
let widgetNumber: Int
let user: String
init?(json:[String:Any]) {
guard let widgetNumber = json["WIDGET_NUMBER"] as? Int,
let user = json["CREATED_BY"] as? String else { return nil }
self.widgetNumber = widgetNumber
self.user = user
}
If you just want an array of widget numbers you could use the reduce function which iterates the dictionaries in the array and extracts the widget numbers:
Using your data I put this in a storyboard:
let json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as! [[String: Any]]
let widgetNumbers = json?.reduce(into: [String]()){ (accum, dict) in
guard let widget = dict["WIDGET_NUMBER"] as? String else { return }
accum.append(widget)
}
widgetNumbers // -> ["K11", "89704"]

Swift and accessing nested JSON collections

I am accessing a CMS with a pre-baked JSON output and it uses the following data structure. I am struggling to get down into the nested collections to get the version or loop through the categories.
{
results: [
{
pageData: {
info: {
version: "1"
},
categories: [
{
name: "Cat 1"
},
{
name: "Cat 2"
}
]
}
}
]
}
Here is the code I was attempting to use. Any help is appreciated!
guard let json = json, let results = json["results"], let pageData = results["pageData"], let info = pageData["info"] as? [String:Int], let version = info["version"],
let categories = Category.getCategories(json: json) else {
self.completionParse(RequestResult.errorParsing, self.categoriesResult)
return
}
To access the info and categories dictionaries you need to first access results Array and pageData that is inside the first object of results array.
guard let json = json, let results = json["results"] as? [[String:Any]],
let firstDic = results.first, let pageData = firstDic["pageData"] as? [String:Any],
let info = pageData["info"] as? [String:Int], let version = info["version"],
let categories = Category.getCategories(json: pageData) else {
self.completionParse(RequestResult.errorParsing, self.categoriesResult)
return
}
Tested below code on playground. This code is in latest swift 3.
if let dictResponse = json as? [String:Any] {
// This will get entire dictionary from your JSON.
if let results = dictResponse["results"] as? [[String:Any]]{
if let pageData = results.first? ["pageData"] as? [String:Any]{
if let info = pageData["info"] as? [String:Any]{
if let version = info["version"] as? String{
print(version)
// This will print 1
}
}
if let categories = pageData["categories"] as? [[String:Any]]{
// This will give you a category array. Later on you can iterate and get the dictionary’s value of each element.
for categoriesObj in categories.enumerated(){
if let name = categoriesObj.element["name"]{
print(name)
}
}
}
}
}
}

Json Parsing in swift 3 using Alamofire

I am working in swift 3. I am new to ios. I am trying to parse the json data like
My jsonVlaue is : {
data = (
{
Password = "#1234";
UserName = "<null>";
"___class" = OrderTable;
"__meta" = "{\"relationRemovalIds\":{},\"selectedProperties\":[\"UserName\",\"created\",\"name\",\"___class\",\"ownerId\",\"updated\",\"objectId\",\"Password\"],\"relatedObjects\":{}}";
created = 1483525854000;
name = TestMan;
objectId = "4316DEBA-78C1-C7BD-FFBC-3CB77D747F00";
ownerId = "<null>";
updated = "<null>";
},
{
Password = 123;
UserName = "<null>";
"___class" = OrderTable;
"__meta" = "{\"relationRemovalIds\":{},\"selectedProperties\":[\"UserName\",\"created\",\"name\",\"___class\",\"ownerId\",\"updated\",\"objectId\",\"Password\"],\"relatedObjects\":{}}";
created = 1483516868000;
name = tommy;
objectId = "29155114-C00B-5E1C-FF6F-7C828C635200";
ownerId = "<null>";
updated = "<null>";
}.......
I want only the keyvalue:"name" and that value I want to add in an Array.
I tried to do like that but my app is getting Crash. My code i slike as follows
func getLoginDetails()
{
//https://api.backendless.com/<version>/data/<table-name>/properties
Alamofire.request( HeadersClass.api.domainName + "OrderTable", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: HeadersClass.allHeaders.headers).responseJSON { response in
//debugPrint(response)
if let jsonDict = response.result.value as? NSDictionary {
print("My jsonVlaue is : \(jsonDict)")
let arrayPracticeData: NSArray = jsonDict.value(forKey: "name") as! NSArray
print(arrayPracticeData)
}
}
}
Can anyone please tell me how to solve this. Thanks in Advance.
First of all in Swift use Swift's native Array and Dictionary instead of NSDictionary and NSArray.
Now to get name you need to get Data array from your JSON response Dictionary. So try something like this.
Alamofire.request( HeadersClass.api.domainName + "OrderTable", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: HeadersClass.allHeaders.headers).responseJSON { response in
//debugPrint(response)
if let jsonDict = response.result.value as? [String:Any],
let dataArray = jsonDict["data"] as? [[String:Any]] {
let nameArray = dataArray.flatMap { $0["name"] as? String }
print(nameArray)
}
}
Output
["TestMan", "tommy", ...]

Swift Facebook Get Friends Graph Request Error

So, I am trying to get a list of all other facebook friends also connected on my app.
After doing an FBSDKgraphrequest, I get the right data (see below) and then convert it to an NSDictionary. The data looks like this:
{
friends = {
data = (
{
id = 10154257515635281;
name = "Hector Judd";
},
{
id = 151132798649181;
name = "Arch Tester Dev";
}
);
paging = {
cursors = {
after = QVFIUndVRFZAINXhCSlAzdnNGeUUwTHdhamNpc3NFbjR2NjF4dk40N3ZAZAR2lNLXM0Q3BxLW90REVsaFk3aU13Um1Ca0NOd0ZAXN2gxaDF2emhYem9BMjhkMVl3;
before = QVFIUlo2a1Q4UGhpWmY2SFNWbUtpMVcxZAnEtR01KSlUyeVEtMU9GbjNkRHp2bTFKY0VoVm5xX3dNLXEwMG5OY0Q0My0ZD;
};
};
summary = {
"total_count" = 831;
};
};
id = 10208811056967519;
}
I then try and unpack it with multiple if let statements, but end up getting the error: Segmentation fault 11. See code below.
func getFriends() {
let parameters = ["fields": "friends"]
FBSDKGraphRequest(graphPath: "me", parameters: parameters).startWithCompletionHandler({ (connection, result, error) -> Void in
if error != nil {
print(error)
} else {
if let result = result as? NSDictionary {
if let data = result["friends"] as? NSDictionary {
if let friendData = data["data"] as? NSArray {
for friend in friendData {
friendIds.append(friend["id"] as String)
print(friendIds)
}
}
}
}
}
})
}
I am relatively new to programming and am struggling to work out a good way to do this. Any suggestions would be much appreciated!! Thanks.
Try to declare your friendData variable as a NSDictionary in your Loop
for friend in friends {
if let friendData = friend as? NSDictionary {
friendIds.append(friendData["id"] as! String)
}
}

Parse nested elements in JSON

I couldn't seem to parse the following json:
["data": {
companies = (
);
"login_status" = success;
"rs_customer" = {
id = "<null>";
name = "<null>";
status = "<null>";
};
user = {
email = "email#email.com";
id = 0;
lastlogin = "06/14/16 12:44 am";
name = "Jayson Tamayo";
password = mypassword;
phone = "112345";
};
}, "status": success]
I retrieve that JSON thru:
HTTPGetJSON("http://myurl.com") {
(data: Dictionary<String, AnyObject>, error: String?) -> Void in
if error != nil {
print(error)
} else {
print(data)
let status = data["status"] as? String
print(status)
}
}
When I print the "status" it works. But when I try to use data["name"] I get nil. I also tried data["data"]["name"] but I also get nil.
Your main object is a dictionary.
In the "data" key, there's several values: "companies" is an array, "rs_customer" is a dictionary, the statuses are Strings and "user" is a dictionary.
So, to get the user, you would just have to cast to the proper types, something like this, if data is the object we see in the question:
if let content = data["data"] as? [String:AnyObject] {
if let user = content["user"] as? [String:AnyObject] {
if let name = user["name"] as? String {
print(name)
}
}
}
You can also chain the unwrapping for simpler code:
if let content = data["data"] as? [String:AnyObject],
user = content["user"] as? [String:AnyObject],
name = user["name"] as? String {
print(name)
}