Unable to Extract Data from the Dictionary<String, Any> in swift - swift

I have a Dictionary<String, Any> Data in the following format. I need to extract the values from it.I am unable to extract the values, initially it looked to me as JSON but it's of type Dictionary<String, Any>. Can anyone help me out.
**{
message = {
"pn_apns" = {
aps = {
alert = {
body = "Andy - Picture added!";
roomId = 1611711512726;
title = "New chat on flag - New flag ";
};
sound = default;
};
};
senderId = "XXXX#XXXXX";
text = "Euclid%20Ave./Flag%20%26%20Chat/New%20flag%20/Original/1AF3956D-AEC4-485C-B8C2-3F97AEE05C58.png";
type = P;
uuid = "XXXXXXX-70CB-4301-DDDD-FFFFFFFF";
};
timetoken = 16117629931914202;
uuid = "XXXX#XXXXX";
}**

This isn't a JSON.
Look at https://www.json.org/json-en.html site.
To check the string, use https://jsonlint.com

Related

Complex Dictionary Get Values as Strings With Conditions

I have built a survey using laanlabs/SwiftSurvey and I am able to get the results from the surveyComplete method as a dictionary.
The results return in a complex structure and I need to get the values for each response by the key tag of the questions array -> question object. This object contains an array of choices and within each choice object there is a key of selected. If the selected key's value is true (1) I need to get the text key's value that is in the same object. Some of these choices will have multiple selected keys with a value of true (1), if this is the case I'd like to concatenate the text key values with a comma in between the values.
The intention is then to insert the keys in to a SQLite database.
I am new to decoding dictionaries and traversing them in the correct way, I can access the dictionary print(dictionary) and also get into the the correct NSArray - print(dictionary["questions"] but from there I am stumped, could someone show me how please.
The results are below unfortunately its a large block apologies.
[
"version": 001,
"metadata":
{
"app_version" = "1.1";
build = 22;
debug = true;
},
"questions": <__NSArrayI 0x600000614d20>(
{
question = {
allowsMultipleSelection = 0;
choices = (
{
allowsCustomTextEntry = 0;
selected = 1;
text = Physician;
uuid = "224E1B76-D220-4068-AA22-6861E5F836CB";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = Dietitian;
uuid = "2DB2B6FB-E344-4BBF-A551-2FABE0DFF6AA";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = "Genetic Counsellor";
uuid = "A9BE7093-B95C-4BF4-B629-12FDA3154ABE";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = "Nurse/Nurse Practitioner/Physician Assistant";
uuid = "8E75A41B-0D8C-4ADA-A31C-2BC408F8269D";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = "Pharmacist / Pharmaceutical Industry";
uuid = "C943430D-EA48-4BCB-8ADF-011A223BDF36";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = "Academic/Researcher";
uuid = "E28377A4-37FC-4351-A857-88383A3D5A3B";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = "Patient/Patient Advocacy Group";
uuid = "E5836187-6C08-4272-A88E-40578F4FCF44";
},
{
allowsCustomTextEntry = 1;
selected = 0;
text = "Other (please specify)";
uuid = "EFF22342-48A9-4B8E-81A0-BB44D0E86EBC";
}
);
required = 1;
tag = "hcp-specialty";
title = "Please select the option that best describes your specialty:";
uuid = "7F77E248-8429-463E-9291-241B94BEE4F8";
};
type = 0;
},
{
question = {
autoAdvanceOnChoice = 1;
choices = (
{
allowsCustomTextEntry = 0;
selected = 1;
text = Yes;
uuid = "3C7A330D-F16B-4F3E-8ABC-6767A1A6332A";
},
{
allowsCustomTextEntry = 0;
selected = 0;
text = No;
uuid = "0E4F5360-FCCD-4860-9971-86E23BB8F6C1";
}
);
required = 1;
tag = "newborn-screening";
title = "Is newborn screening for classical homocystinuria available in your region/country?";
uuid = "F7C1A9D5-43AB-420D-80CF-F6644B95C73E";
};
type = 1;
},
{
question = {
feedback = "This is a free text response";
required = 1;
tag = "biggest-unmet-need";
title = "What do you believe is the biggest unmet need for patients living with classical HCU?";
uuid = "133E2EDC-8FF4-48D1-8BFA-3A20E5DA0052";
};
type = 4;
}
)
]
Based on their result example, you are getting JSON. Converting JSON to Dictionary is the easiest, of course, but also is the dirtiest. You are basically getting "whatever", so when it's time to use the data, you have to do a lot of - as you said - "decoding", validation, etc.
Instead of that, create a few Decodable structures that match your response. In this case you just need 3 structures:
struct Survey: Codable {
let questions: [Question]
}
struct Question: Codable {
let allowsMultipleSelection: Int?
let choices: [Choice]?
let required: Int
let tag: String
let title: String
let uuid: String
let feedback: String?
}
struct Choice: Codable {
let allowsCustomTextEntry: Int
let selected: Int
let text: String
let uuid: String
}
(I didn't verify every fields, you can adjust as needed. And you can omit any properties you don't need / don't care about.)
And then you decode it like this:
// Assume jsonData is your original JSON, which you currently decode as dictionary. So instead you do this:
let decoder = JSONDecoder()
let product = try decoder.decode(Survey.self, from: jsonData)
This approach allows you to
Most importantly, having a well-defined data makes working with database easier. You can even implement database encoder, based on your codable structures, which means you don't need to manually walk through columns of the database. Also when. you read from database, you get the same structures, no need to have 2 sets of rules / validations for database and dictionary you decoded.
This also allows you to be confident about data you decoded: it has proper names and types. You don't need to validate it (it was validated for you on decoding). You are in control which properties are required, which defaults to set, and so on. In more complicated cases, you may need to add manual decoding to your structures, but even then this manual decoding is inside the structure itself, easy to change / work with / test. All this instead of giant messy dictionary with "some stuff" in it.

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.
}

Swift, dictionary parse error

I'm using an API to get weather condition and the retrieved dict is
dict = {
base = stations;
clouds = {
all = 92;
};
cod = 200;
coord = {
lat = "31.23";
lon = "121.47";
};
dt = 1476853699;
id = 1796231;
main = {
"grnd_level" = "1028.63";
humidity = 93;
pressure = "1028.63";
"sea_level" = "1029.5";
temp = "73.38";
"temp_max" = "73.38";
"temp_min" = "73.38";
};
name = "Shanghai Shi";
rain = {
3h = "0.665";
};
sys = {
country = CN;
message = "0.0125";
sunrise = 1476827992;
sunset = 1476868662;
};
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
wind = {
deg = "84.50239999999999";
speed = "5.97";
};
}
If I want the value of humidity, I just use
let humidityValue = dict["main"]["humidity"] and it works.
But the problem is I also want to get the value of description in weather
when I used let dscptValue = dict["weather"]["description"]
it retrieved nil.
How's that? and I notice there are two brackets around weather .I'm not sure whether it is the same with the statement without brackets.
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
How to get the value of description?
weather keys contains Array of Dictionary not directly Dictionary, so you need to access the first object of it.
if let weather = dict["weather"] as? [[String: AnyObject]], let weatherDict = weather.first {
let dscptValue = weatherDict["description"]
}
Note: I have used optional wrapping with if let for preventing crash with forced wrapping.
Weather is an array of dictionaries.
dict["weather"][0]["description"]
may give you the expected result.

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.

how to save json value in sqlite database in iphone

hi friend this is my JSON file apitest[18318:207] { ErrorCode = 900; ErrorMessage = ""; Result = ( { DeviceInfoId = 12; Email = "rocky#itg.com"; FirstName = Rocky; LastName = Yadav; ProfileImage = "<null>"; ThumbnailImage = "<null>"; UserId = 153; } ); TokenID = 59nUniliob; isError = 0; }
Can you please explain me how to parse the above JSON file and save the values in sqlite database this
You can use the SBJson parser to get a dictionary/array out of a json (depending on your response). You can then get the individual values from the dictionary/array and save them into your database.
The git repo also has some examples on how to use the parser.