Get data from json array swift 2 - json

I'm trying to get data drom the json array, this is the code that i'm trying, the thing is that i would like to get only the name that is inside this json
{
"tag": "getuser",
"success": 1,
"error": 0,
"uid": "56108b7e651ad2.95653404",
"user": {
"name": "2",
"phone": "2",
"email": "2"
}
}
I tryied this
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
let name = jsonData["user"]
print("Nombre del usuarioes: \(name)")
But this prints the whole user data, name, phone and email, how can i be able to print only the name or only the email?

You don't have to use a library and you don't have to use key-value coding.
The same way you're already using subscripting for your dictionary with this:
let name = jsonData["user"]
you just have to continue subscripting to find your value.
Example:
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(urlData!, options: []) as! NSDictionary
let user = jsonData["user"]!
let name = user["name"]
print(name)
} catch {
print(error)
}
Even better with safe unwrapping:
do {
if let data = urlData, let jsonData = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary {
if let user = jsonData["user"] as? NSDictionary, let name = user["name"] as? String {
print(name)
}
}
} catch {
print(error)
}
Note: in JSON, a dictionary is defined by {} and an array is defined by []. What you have here is a dictionary containing a dictionary, not an array (cf your question title).

A great library to decode json is SwiftyJSON
you can get sub-scripted data from the json like so
import SwiftyJSON
if let dataFromString = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
let name = json["user"]["name"].string
print(name)
}

Use your code, then get the field from jsonData by this:
let name = jsonData.valueForKeyPath("user.name") as! String
let email = jsonData.valueForKeyPath("user.email") as! String

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"]

Retrieving JSON elements in Swift 3

I have following JSON file
{
"events": [
{
"date": "01/11/2017",
"name": [
"Tulsi Vivah",
"Pradosh Vrat"
],
"photo": [
"photo_chaturthi",
"photo_ekadashi"
]
},
{
"date": "03/11/2017",
"name": [
"Guru Nanak Jayanti"
],
"photo": [
"photo_chaturthi",
"photo_ekadashi"
]
}
]
}
I want to parse this and put the elements in the objectArray in the code below:
struct Objects {
var sectionName : String!
var sectionObjects : [String]!
var sectionImages : [String]!
}
var objectArray = [Objects]()
I have written following code for reading the file:
if let file = Bundle.main.url(forResource: "EventsEnglish112017", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data as Data, options: [])
My question is how do I typecast "json" to read the individual elements to fill the above objectArray.
Thanks!
A JSON is a dictionary of type [String:Any?]
To parse it:
if let dictionary = json as? [String: Any?] {
if let events = dictionary["events"] as? [[String: Any?]] {
// events is an array of JSON objects, so it's an array of dictionaries
for item in events
{
let date = item["date"] as? String // this is a String?
let name = item["name"] as? [String]
// same goes for 'photo'
}
}
}
Now that you have retrieved the data, you can use it to costruct your custom objects.
But it's better if you use some library that will make it for you, or use Swift4
To retrieve data from JSON file
(Swift 3)
if let path = NSBundle.mainBundle().pathForResource("myJson", ofType: "json")
{
if let jsonData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)
{
if let jsonResult = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? [String: Any]
{
if let eventsInfo = jsonResult["events"] as? [Any]
{
// Here you will get your data in Array format.
// for e.g
// print(eventsInfo[0]["date"])
// Just pass this eventsInfo (Array) into you Object model initializer and parse with the keys there.
}
}
}
}
(Swift 4)
if let path = Bundle.main.path(forResource: "myJson", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? Dictionary<String, AnyObject>, let eventsInfo = jsonResult["events"] as? [Any] {
// Here you will get your data in Array format.
// for e.g
// print(eventsInfo[0]["date"])
// Just pass this eventsInfo (Array) into you Object model initializer and parse with the keys there.
}
} catch {
// handle error
}
}

The JSON output does not contain a key: "value"

I have a JSON parsing issue with my Swift code below. The error I am getting says that my JSON output does not contain a key value.
My code:
Alamofire.request(url, method: .get, headers: headers).responseJSON { (response) -> Void in
let jsonValue = response.result.value as! NSDictionary
if let bpArray = jsonValue["value"] as? [NSDictionary]{
for results in bpArray {...}
Issue:
This conversion doesnt work: if let bpArray = jsonValue["value"] as? [NSDictionary]
My JSON Structure:
{
d: {
results: [
{
__metadata: {},
Key: "AFBWhULFHtKU4j4FhWCmKg==",
ParentKey: "AAAAAAAAAAAAAAAAAAAAAA==",
RootKey: "AFBWhULFHtKU4j4FhWCmKg==",
Partner: "MM-CARR-01",
Type: "2",
Description: "MM Demo Carrier Created for Single Stop / MA",
FrieghtOrder: {}
},
...
Assuming you want to access the results key so try like this:-
if let bpArray = jsonValue["results"] as? [String: AnyObject]{
//yourcode
}
Well your json structure haven't got any key named as value and that's why it's giving an error.
In order to get results array, you first need to get the object in which they are nested and for example 'g' in your case:
if let data = jsonValue["d"] as? [NSDictionary]{
if let resultsArray = data["results"] as? NSArray {
//your code
}
}
Please Use Swifty Json Pod And Try this code
pod 'SwiftyJSON'
In Your file where you get response
import SwiftyJSON
Then After Use This Code
switch response.result {
case .success(let JSON2):
print("Success with JSON: \(JSON2)")
// print("Request failed with error: \(response.response?.statusCode)")
if let response = JSON2 as? NSMutableDictionary
{
}
else if let response = JSON2 as? NSDictionary
{
if let data = response?.object(forKey: "d") as? NSDictionary
{
if let resultsArray = data?.object(forKey: "results") as? NSArray
{
}
}
}
else if JSON2 is NSArray
{
let swjson = JSON(response.result.value!)
print(swjson)
// callback(swjson,nil)
var myMutableDictionary = [AnyHashable: Any]()
myMutableDictionary["myArray"] = swjson
callback(myMutableDictionary as NSDictionary?,nil)
print("accc")
}
else if ((JSON2 as? String) != nil)
{
let userDic : [String : String] = ["quatid":JSON2 as! String]
print(userDic)
}
break
case .failure(let error):
print("Request failed with error: \(error)")
}
Remember it's better we not use NSArray & NSDictionary like things in SWIFT, SWIFT it self providing let, var keyword for various data type.
First you can create your model where you can save the data.
MyModel.swift
class MyModel: NSObject {
var ParentKey : Int?
init(jsonObject:[String:Any]) {
ParentKey = jsonObject["ParentKey"] as? String ?? ""
}
}
Viewcontroller.Swift
var myModel : [MyModel] = []
if let responseData = response["d"] as? [String:Any]{
if let dataObject = responseData["results"] as? [[String:Any]]{
self.myModel = dataObject.map({return MyModel(jsonObject: $0)})//for assigning data into model
}
}
As most people said, I was wrong with "value". Hussain's answer to using [String:AnyObject] Helped.
I am not sure if the below is neat to achieve, but it did the magic. App loaded as expected. Code expert below:
Solution:
if let bpData = jsonValue["d"] as? [String: AnyObject]{
for results in bpData {
let arrayInterim = results.value as? NSArray
for i in 0 ..< arrayInterim!.count {

How to convert array of string values to escaped jSON Array in iOS? [duplicate]

How do you convert an array to a JSON string in swift?
Basically I have a textfield with a button embedded in it.
When button is pressed, the textfield text is added unto the testArray.
Furthermore, I want to convert this array to a JSON string.
This is what I have tried:
func addButtonPressed() {
if goalsTextField.text == "" {
// Do nothing
} else {
testArray.append(goalsTextField.text)
goalsTableView.reloadData()
saveDatatoDictionary()
}
}
func saveDatatoDictionary() {
data = NSKeyedArchiver.archivedDataWithRootObject(testArray)
newData = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(), error: nil) as? NSData
string = NSString(data: newData!, encoding: NSUTF8StringEncoding)
println(string)
}
I would also like to return the JSON string using my savetoDictionart() method.
As it stands you're converting it to data, then attempting to convert the data to to an object as JSON (which fails, it's not JSON) and converting that to a string, basically you have a bunch of meaningless transformations.
As long as the array contains only JSON encodable values (string, number, dictionary, array, nil) you can just use NSJSONSerialization to do it.
Instead just do the array->data->string parts:
Swift 3/4
let array = [ "one", "two" ]
func json(from object:Any) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: object, options: []) else {
return nil
}
return String(data: data, encoding: String.Encoding.utf8)
}
print("\(json(from:array as Any))")
Original Answer
let array = [ "one", "two" ]
let data = NSJSONSerialization.dataWithJSONObject(array, options: nil, error: nil)
let string = NSString(data: data!, encoding: NSUTF8StringEncoding)
although you should probably not use forced unwrapping, it gives you the right starting point.
Swift 3.0 - 4.0 version
do {
//Convert to Data
let jsonData = try JSONSerialization.data(withJSONObject: dictionaryOrArray, options: JSONSerialization.WritingOptions.prettyPrinted)
//Convert back to string. Usually only do this for debugging
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 [Any].
var json = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
} catch {
print(error.description)
}
The JSONSerialization.WritingOptions.prettyPrinted option gives it to the eventual consumer in an easier to read format if they were to print it out in the debugger.
Reference: Apple Documentation
The JSONSerialization.ReadingOptions.mutableContainers option lets you mutate the returned array's and/or dictionaries.
Reference for all ReadingOptions: Apple Documentation
NOTE: Swift 4 has the ability to encode and decode your objects using a new protocol. Here is Apples Documentation, and a quick tutorial for a starting example.
If you're already using SwiftyJSON:
https://github.com/SwiftyJSON/SwiftyJSON
You can do this:
// this works with dictionaries too
let paramsDictionary = [
"title": "foo",
"description": "bar"
]
let paramsArray = [ "one", "two" ]
let paramsJSON = JSON(paramsArray)
let paramsString = paramsJSON.rawString(encoding: NSUTF8StringEncoding, options: nil)
SWIFT 3 UPDATE
let paramsJSON = JSON(paramsArray)
let paramsString = paramsJSON.rawString(String.Encoding.utf8, options: JSONSerialization.WritingOptions.prettyPrinted)!
JSON strings, which are good for transport, don't come up often because you can JSON encode an HTTP body. But one potential use-case for JSON stringify is Multipart Post, which AlamoFire nows supports.
How to convert array to json String in swift 2.3
var yourString : String = ""
do
{
if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(yourArray, options: NSJSONWritingOptions.PrettyPrinted)
{
yourString = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
}
}
catch
{
print(error)
}
And now you can use yourSting as JSON string..
Swift 5
This generic extension will convert an array of objects to a JSON string from which it can either be:
saved to the App's Documents Directory (iOS/MacOS)
output directly to a file on the Desktop (MacOS)
.
extension JSONEncoder {
static func encode<T: Encodable>(from data: T) {
do {
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let json = try jsonEncoder.encode(data)
let jsonString = String(data: json, encoding: .utf8)
// iOS/Mac: Save to the App's documents directory
saveToDocumentDirectory(jsonString)
// Mac: Output to file on the user's Desktop
saveToDesktop(jsonString)
} catch {
print(error.localizedDescription)
}
}
static private func saveToDocumentDirectory(_ jsonString: String?) {
guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let fileURL = path.appendingPathComponent("Output.json")
do {
try jsonString?.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print(error.localizedDescription)
}
}
static private func saveToDesktop(_ jsonString: String?) {
let homeURL = FileManager.default.homeDirectoryForCurrentUser
let desktopURL = homeURL.appendingPathComponent("Desktop")
let fileURL = desktopURL.appendingPathComponent("Output.json")
do {
try jsonString?.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print(error.localizedDescription)
}
}
}
Example:
struct Person: Codable {
var name: String
var pets: [Pet]
}
struct Pet: Codable {
var type: String
}
extension Person {
static func sampleData() -> [Person] {
[
Person(name: "Adam", pets: []),
Person(name: "Jane", pets: [
Pet(type: "Cat")
]),
Person(name: "Robert", pets: [
Pet(type: "Cat"),
Pet(type: "Rabbit")
])
]
}
}
Usage:
JSONEncoder.encode(from: Person.sampleData())
Output:
This will create the following correctly formatted Output.json file:
[
{
"name" : "Adam",
"pets" : [
]
},
{
"name" : "Jane",
"pets" : [
{
"type" : "Cat"
}
]
},
{
"name" : "Robert",
"pets" : [
{
"type" : "Cat"
},
{
"type" : "Rabbit"
}
]
}
]
SWIFT 2.0
var tempJson : NSString = ""
do {
let arrJson = try NSJSONSerialization.dataWithJSONObject(arrInvitationList, options: NSJSONWritingOptions.PrettyPrinted)
let string = NSString(data: arrJson, encoding: NSUTF8StringEncoding)
tempJson = string! as NSString
}catch let error as NSError{
print(error.description)
}
NOTE:- use tempJson variable when you want to use.
extension Array where Element: Encodable {
func asArrayDictionary() throws -> [[String: Any]] {
var data: [[String: Any]] = []
for element in self {
data.append(try element.asDictionary())
}
return data
}
}
extension Encodable {
func asDictionary() throws -> [String: Any] {
let data = try JSONEncoder().encode(self)
guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
throw NSError()
}
return dictionary
}
}
If you're using Codable protocols in your models these extensions might be helpful for getting dictionary representation (Swift 4)
Hint: To convert an NSArray containing JSON compatible objects to an NSData object containing a JSON document, use the appropriate method of NSJSONSerialization. JSONObjectWithData is not it.
Hint 2: You rarely want that data as a string; only for debugging purposes.
For Swift 4.2, that code still works fine
var mnemonic: [String] = ["abandon", "amount", "liar", "buyer"]
var myJsonString = ""
do {
let data = try JSONSerialization.data(withJSONObject:mnemonic, options: .prettyPrinted)
myJsonString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
} catch {
print(error.localizedDescription)
}
return myJsonString
Swift 5
Make sure your object confirm Codable.
Swift's default variable types like Int, String, Double and ..., all are Codable that means we can convert theme to Data and vice versa.
For example, let's convert array of Int to String Base64
let array = [1, 2, 3]
let data = try? JSONEncoder().encode(array)
nsManagedObject.array = data?.base64EncodedString()
Make sure your NSManaged variable type is String in core data schema editor and custom class if your using custom class for core data objects.
let's convert back base64 string to array:
var getArray: [Int] {
guard let array = array else { return [] }
guard let data = Data(base64Encoded: array) else { return [] }
guard let val = try? JSONDecoder().decode([Int].self, from: data) else { return [] }
return val
}
Do not convert your own object to Base64 and store as String in CoreData and vice versa because we have something that named Relation in CoreData (databases).
For Swift 3.0 you have to use this:
var postString = ""
do {
let data = try JSONSerialization.data(withJSONObject: self.arrayNParcel, options: .prettyPrinted)
let string1:String = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
postString = "arrayData=\(string1)&user_id=\(userId)&markupSrcReport=\(markup)"
} catch {
print(error.localizedDescription)
}
request.httpBody = postString.data(using: .utf8)
100% working TESTED
You can try this.
func convertToJSONString(value: AnyObject) -> String? {
if JSONSerialization.isValidJSONObject(value) {
do{
let data = try JSONSerialization.data(withJSONObject: value, options: [])
if let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
return string as String
}
}catch{
}
}
return nil
}

How to parse this specific JSON data in Swift 2.0

I'm trying to parse Json Data from an API :
{
"title": "Mr. Robot",
"first_aired": "2015-06-24",
"network": "USA Network",
"channels": [
{
"id": 12,
"name": "USA",
"short_name": "usa",
"channel_type": "television"
}
],
The Code I'm use is:
var TVArray : [TVInfo] = []
var task : NSURLSessionTask?
func getJSON (urlString: String) {
let url = NSURL(string: urlString)!
let session = NSURLSession.sharedSession()
task = session.dataTaskWithURL(url) {(data, response, error) in
dispatch_async(dispatch_get_main_queue()) {
if (error == nil) {
self.updateJSON(data)
}
else {
}
}
}
task!.resume()
}
func updateJSON (data: NSData!) {
let JSONData = (try! NSJSONSerialization.JSONObjectWithData(data, options: []))
TVArray.removeAll(keepCapacity: true)
if let jsonArray = JSONData {
for j in jsonArray {
let title = jsonResult["title"] as! String
let firstAired = jsonResult["first_aired"] as! String
let network = jsonResult["network"] as! String
let channelName = JsonResult["channels"][0]["name"] as! String
let TV = TVInfo(title: title, firstAired: firstAired, network: network, channelName: channelName)
TVArray.append(TV)
}
}
collectionview.reloadData()
}
}
When I use the above code I get an error 'Initializer for conditional binding must have Optional type, not 'AnyObject'' in front of the line 'if let jsonArray = JsonData'. I've tried some methods I've seen on StackOverflow like the method in the link :
[Parsing JSON in swift 2.0
but it didn't work for me. I'm still a bit new to Swift, I really don't want to use SwiftyJSON. Is this the best way to parse this JSON data or is there a better way of doing it?
Since you've used NSJSONSerialization with try! (note the !, meaning it was forced) the value of JSONData is not an optional: you don't have to unwrap it with if let jsonArray = JSONData.
If you still want an optional value, use try? instead.
Otherwise you could also use try inside a do catch block to handle possible errors.
The type of JSONData is unknown, it needs to be known to be an Array for the following for loop.
use:
let JSONData = try! NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! NSArray
You do not need:
if let jsonArray = JSONData {
because you have already crashed if JSONData is nil from the preceding try!
You are better with:
do {
let jsonArray = try NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! NSArray
for j in jsonArray {
// ...
}
} catch {
// handle error
}
Because you have no control over the JSON you receive and crashing because of a server change is not a good idea.
Also really put some time into naming variables, JSONData is not data, it is an array obtained by parsing a JSON string.