iOS swift separate JSON into array - ios

I have a JSON file like this:
{
"timeline": {
"Milan": {
"placeA": [
{
"name": "Place 1",
"kind": "historic",
},
{
"name": "Place 2",
"kind": "historic",
},
{
"name": "Place 3",
"kind": "historic",
}
]
},
"Paris": {
"placeB": [
{
"name": "Place 1",
"kind": "historic",
},
{
"name": "Place 2",
"kind": "historic",
}
]
}
}
}
and in my app I need to separate this JSON and insert into a array like this for separate data with tableView section:
var arr = [[placeA],[placeB],...]
how can I do that?
P.S I use SwiftyJson

struct City {
let name : String
let kind : String
}
var cities = [City]()
let path = (try? Data(contentsOf: URL(string: "http://www.yourwebsite.json")!)) as Data!
// let jsonData = NSData(contentsOfFile: path) as NSData!
var error : NSError?
let ReadableJSON2 = JSON ( data:path!, options: JSONSerialization.ReadingOptions.mutableContainers, error: nil )
print(error)
do {
let jsonObject = try JSONSerialization.jsonObject(with: path!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
for city in jsonObject["cities"] as! [[String:AnyObject]] {
//let coordinates = position["Position"] as! [String:CLLocationDegrees]
let Cityname = city["name"] as! String
let Citykind = city["kind"] as! String
let city = City(name: cityName,description: description, )
cities.append(city)
}
} catch let error as NSError {
print(error)
}

Related

JSON structure with Swift and Alamofire

Following on from This question
I am trying to bring in the summary field but it has a further value. I have brought in the title and author as follows:
func parseData(JSONData : Data) {
do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONstandard
// print(readableJSON)
if let posts = readableJSON["posts"] as? [JSONstandard] {
for post in posts {
let title = post["title"] as! String
let author = post["author"] as! String
let summary = post["summary"] as! String
print(author)
if let imageUrl = post["image"] as? String {
let mainImageURL = URL(string: imageUrl )
let mainImageData = NSData(contentsOf: mainImageURL!)
let mainImage = UIImage(data: mainImageData as! Data)
postsinput.append(postinput.init(mainImage: mainImage, name: title, author: author, summary: summary))
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
catch {
print(error)
}
}
But if i try the summary that way a error is returned. Any help would be appreciated.
JSON STRUCTURE
{
"posts" : [{
"id": "000000",
"url": "/content/interview2",
"date": "2016-11-03 09:01:41",
"modified": "2016-11-03 09:03:47",
"title": "An interview",
"image": "https://www.example.com/sites/default/files/oregood.jpeg",
"summary": {
"value": "<p>Latin text here</p>",
"format": "filtered_html"
}
}]
}
From your previous question response, summary key contains the Dictionary so you can try like this.
guard let dic = post["summary"] as? [String: Any], let summary = dic["value"] as? String else {
return
}

Swift and JSON parsing only an object not an array

I am working on a weather app that parses JSON data and sets the text of my label to the temp value of the JSON request. I got the value of id from the weather object array, but the temp is not in an array it is just an object. Can someone please tell me where I am wrong. My value is reurning nil because I am not fetching it correctly. Here is my snippet and JSON.
#IBAction func getWeather(sender: AnyObject) {
let requestURL: NSURL = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=MYAPPID")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("JSON Downloaded Sucessfully.")
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
if let today = json["weather"] as? [[String: AnyObject]] {
//this is pulling 4 key value pairs
for weather in today {
//this works
let id = weather["id"]?.stringValue
self.trumpDescription.text=id;
print(id)
//this is where I am confused it changes from an array to just an object
let temp = json["temp"] as? String
self.currentTempView.text=temp;
print(temp)
}
}
}
catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
}`
Here is the JSON:
{
"coord": {
"lon": 138.93,
"lat": 34.97
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"base": "cmc stations",
"main": {
"temp": 292.581,
"pressure": 1019.48,
"humidity": 99,
"temp_min": 292.581,
"temp_max": 292.581,
"sea_level": 1028.92,
"grnd_level": 1019.48
},
"wind": {
"speed": 5.36,
"deg": 237.505
},
"clouds": {
"all": 64
},
"dt": 1464964606,
"sys": {
"message": 0.0037,
"country": "JP",
"sunrise": 1464895855,
"sunset": 1464947666
},
"id": 1851632,
"name": "Shuzenji",
"cod": 200
}
It looks like it should be
if let main = json["main"] as? NSDictionary {
let temp = main["temp"] as! String
print(temp)
}
Instead of this:
let temp = json["temp"] as? String
Try this:
if let main = json["main"] as? [String: AnyObject] {
let temp = main[temp]?.stringValue
print(temp)
//alternatively you can try this as per your convenience of data type
let tempNew = main[temp]?.doubleValue
print(tempNew)
}

NSJSONSerialization return nil with a valid json

I try to parse a response which return a valid JSON with NSJSonSerialization. But it returns nil with no error. It works with another JSON response.
I did some search, and this could be a problem with the encoding of the JSON. I don't know how to solve it. Any idea ?
let url: NSURL = NSURL(string: urlPath)!
self.searchRequest = NSMutableURLRequest(URL: url)
if let searchRequest = self.searchRequest {
searchRequest.HTTPMethod = "GET"
let authString : String = SNCF.APIKey + ":" + ""
let authData : NSData = authString.dataUsingEncoding(NSASCIIStringEncoding)!
let authValue : String = "Basic " + authData.base64EncodedStringWithOptions(.EncodingEndLineWithCarriageReturn)
searchRequest.setValue(authValue, forHTTPHeaderField: "Authorization")
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(searchRequest, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
//HERE JSONRESULT WILL BE NIL
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: [AnyObject]] {
print("ASynchronous\(jsonResult)")
if let places = jsonResult["stop_areas"] as? [[String:AnyObject]]{
for placeDictionary in places {
if let labelText = placeDictionary["label"] as? String {
self.resultDatasource.append(labelText)
}
}
self.resultTableView.reloadData()
}
}
//HERE NO ERROR IS CATCHED
} catch let error as NSError {
print(error.localizedDescription)
}
})
Piece of my json response :
{
"disruptions": [],
"pagination": {
"start_page": 0,
"items_on_page": 100,
"items_per_page": 100,
"total_result": 3053
},
"stop_areas": [
{
"codes": [
{
"type": "CR-CI-CH",
"value": "0080-251967-BV"
}
],
"name": "gare de Perl",
"links": [],
"coord": {
"lat": "0",
"lon": "0"
},
"label": "gare de Perl",
"timezone": "Europe/Paris",
"id": "stop_area:OCE:SA:80251967"
},
{
...
},
//stop_areas dictionaries object...
], //end stop_areas array of dictionaries
"links": [
{
"href": "https://api.sncf.com/v1/coverage/sncf/stop_areas/{stop_areas.id}",
"type": "stop_areas",
"rel": "stop_areas",
"templated": true
},
{
"href": "https://api.sncf.com/v1/coverage/sncf/stop_areas?start_page=1",
"type": "next",
"templated": false
},
{
"href": "https://api.sncf.com/v1/coverage/sncf/stop_areas?start_page=30.52",
"type": "last",
"templated": false
},
{
"href": "https://api.sncf.com/v1/coverage/sncf/stop_areas",
"type": "first",
"templated": false
}
],
"feed_publishers": [
{
"url": "",
"id": "sncf",
"license": "",
"name": ""
}
]
}
The type of the JSON is [String: AnyObject] not [String: [AnyObject]]
I think this is the problem:
as? [String: [AnyObject]]
Try to remove the cast. If your JSON is correct and has no validation errors, the dictionary you get probably has the key value of type Any. You can try to use the dictionary by only casting the value keys you want:
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: nil) {
print("ASynchronous\(jsonResult)")
if let places = jsonResult["stop_areas"] as? [[String:AnyObject]] {
...
}
}
Try This
do {
if let jsonResult: Dictionary = try NSJSONSerialization.JSONObjectWithData(self.mutableData, options: NSJSONReadingOptions.MutableContainers) as? Dictionary<String, AnyObject>
{
// print("get Read messages == \(jsonResult)");
if ((jsonResult["Warning"]) != nil)
{
let error_by_wc: NSString = jsonResult["Warning"] as! String
//print("results == \(error_by_wc)");
// printMessage("\(error_by_wc)")
JLToast.makeText("\(error_by_wc)").show()
}else if((jsonResult["Error"]) != nil)
{
let error_by_wc: NSString = jsonResult["Error"] as! String
// print("results == \(error_by_wc)");
// printMessage("\(error_by_wc)")
JLToast.makeText("\(error_by_wc)").show()
}
else
{
// read message s
}
} catch {
print(error)
}
If Data is Array Type Use this code
do {
if let jsonResult:NSArray = try NSJSONSerialization.JSONObjectWithData(self.mutableData, options: .MutableContainers) as? NSArray {
//print(jsonResult)
aDataBase.insertFromUserImage(jsonResult)
connection_allMEssages()
}else
{
//print("not data found")
BProgressHUD.dismissHUD(0)
}
} catch {
print(error)
BProgressHUD.dismissHUD(0)
}

Accessing JSON with Swift

I am currently developing an app and I want to display some information about a particular place. I am using Google Places API to do this and am trying to extract some information from this JSON response:
{
"html_attributions": [],
"result": {
"address_components": [],
"adr_address": "5, \u003cspan class=\"street-address\"\u003e48 Pirrama Rd\u003c/span\u003e, \u003cspan class=\"locality\"\u003ePyrmont\u003c/span\u003e \u003cspan class=\"region\"\u003eNSW\u003c/span\u003e \u003cspan class=\"postal-code\"\u003e2009\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eAustralia\u003c/span\u003e",
"formatted_address": "5, 48 Pirrama Rd, Pyrmont NSW 2009, Australia",
"formatted_phone_number": "(02) 9374 4000",
"geometry": {},
"icon": "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id": "4f89212bf76dde31f092cfc14d7506555d85b5c7",
"international_phone_number": "+61 2 9374 4000",
"name": "Google",
"photos": [],
"place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
"rating": 4.5,
"reference": "CmRaAAAAVvEJLOszIgZMqrn59xg_wEmLJUpC52Zd7HZzzcv0OsaRobY_f8galxBVNsyEgC9nhUsI7BQQcTYCA0t_f8JlhEV-dftt-OhapkRRvQ12g6R3FU-d6OWB-T1vYVIcRuEBEhBha4swICH7pUUsjBRivnHTGhT1Y97NAmr0iWe4qffGJH0iY96GKg",
"reviews": [],
"scope": "GOOGLE",
"types": [
"point_of_interest",
"establishment"
],
"url": "https://maps.google.com/?cid=10281119596374313554",
"user_ratings_total": 133,
"utc_offset": 660,
"vicinity": "5 48 Pirrama Road, Pyrmont",
"website": "https://www.google.com.au/about/careers/locations/sydney/"
},
"status": "OK"
}
The code I am using in my view controller is:
let reposURL = NSURL(string: "https://maps.googleapis.com/maps/api/place/details/json?placeid=\(chosenPlaceID!)&key=SOMEAPIKEY")!
if let JSONData = NSData(contentsOfURL: reposURL) {
if let json = (try? NSJSONSerialization.JSONObjectWithData(JSONData, options: [])) as? NSDictionary {
if let reposArray = json["result"] as? [NSDictionary] {
for item in reposArray {
placeRepositories.append(PlaceRepository(json: item ))
}
}
}
}
The code in my placeRepository controller is:
class PlaceRepository {
var name: String?
var formattedAddress: String?
var formattedPhoneNumber: String?
var internationPhoneNumber: String?
var types: [String]?
init(json: NSDictionary) {
self.name = json["name"] as? String
self.formattedAddress = json["formatted_address"] as? String
self.formattedPhoneNumber = json["formatted_phone_number"] as? String
self.internationPhoneNumber = json["international_phone_number"] as? String
self.types = json["types"] as? [String]
}
}
I have put a breakpoint in to try and find out what is going on and the for item in reposArray code is never accessed, it gets skipped over in the previous if statement but I am not sure why? Any help would be greatly appreciated.
Thank you.
Your response suggests json["result"] is not array of dictionary ... [NSDictionary] ... its NSDictionary
change this line
if let reposArray = json["result"] as? [NSDictionary] { ... }
with
if let reposArray = json["result"] as? NSDictionary {
PlaceRepository(json: reposArray )
}
After that you can't loop NSDictionary like
for item in reposArray { .. }
You can use third party libraries like SwiftyJson It's make JSON parsing more easy task.

Swift IOS Reading JSON from url

On the below method, I can get the place value but not the location value. how can I get the location?
Thank you in advance!!
func searchDB(looking: String){
var urlString:String = "URLGOESHERE?q=\(looking)"
let url = NSURL(string: urlString)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if error != nil {
println(error)
}
else {
//processing data
if let arr = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [AnyObject] {
for currPlace in arr {
println(currPlace["name"])
println(currPlace["location"])
}
}
else {
errorOccurred = true
}
}//eo potential data
})
task.resume()
}//eom
This is the result output I am getting:
Optional(Buddha-Bar)
Optional(nil)
JSON sample:
sample data:
{
"formatted_address": "8-12 Rue Boissy d'Anglas, 75008 Paris, France",
"geometry": {
"location": {
"lat": 48.868194,
"lng": 2.321596
}
},
"icon": "http://maps.gstatic.com/mapfiles/place_api/icons/bar-71.png",
"id": "560dd225114fd10997f75ee777bad84bcb40c529",
"name": "Buddha-Bar",
"opening_hours": {
"open_now": true,
"weekday_text": []
},
"photos": [
{
"height": 848,
"html_attributions": [],
"photo_reference": "CnRnAAAAifUh9MiqwAgQYdwEp-EnS4e_nPQN_mPYIqdI49UKun_CZKxgtUh_ZqT8QBEqBuel9seoZvyyIVvA5-TlweEqO9_2tORg_cmTi_Cy5L_PAthdZd1_Krqbf7oJNy81RWD3brA8fzeIKJfQTMgo-AT19RIQAg5kKSqeoeedm69uhUWKvBoULDJ1-PoSgv4Lsg5y1rjU_pHm_Ng",
"width": 1919
}
],
"place_id": "ChIJRS81ac1v5kcRRUqQBmTTJJU",
"price_level": 3,
"rating": 3.7,
"reference": "CmReAAAAjJskNN69nw3gBVtqLpsX11Psr-QvK6cHPLhF-oDXAbYq7dwLn65b1svUJOLVnRgAbg4K3w7qCj9_hkXvx20q4YNR2714ZQQw89GyFGCtXAxonRh09_uvgK97DewsYRyUEhAczR_GzOvU0mmG1OZr0X3kGhQeJ1Vr3RSnI6VXyzh83W_LIcUK_g",
"types": [
"bar",
"restaurant",
"food",
"establishment"
]
},
Json data without spaces
sample data:
{
"formatted_address": "8-12 Rue Boissy d'Anglas, 75008 Paris, France",
"geometry": {
"location": {
"lat": 48.868194,
"lng": 2.321596
}
},
"icon": "http://maps.gstatic.com/mapfiles/place_api/icons/bar-71.png",
"id": "560dd225114fd10997f75ee777bad84bcb40c529",
"name": "Buddha-Bar",
"opening_hours": {
"open_now": true,
"weekday_text": []
},
"photos": [
{
"height": 848,
"html_attributions": [],
"photo_reference": "CnRnAAAAifUh9MiqwAgQYdwEp-EnS4e_nPQN_mPYIqdI49UKun_CZKxgtUh_ZqT8QBEqBuel9seoZvyyIVvA5-TlweEqO9_2tORg_cmTi_Cy5L_PAthdZd1_Krqbf7oJNy81RWD3brA8fzeIKJfQTMgo-AT19RIQAg5kKSqeoeedm69uhUWKvBoULDJ1-PoSgv4Lsg5y1rjU_pHm_Ng",
"width": 1919
}
],
"place_id": "ChIJRS81ac1v5kcRRUqQBmTTJJU",
"price_level": 3,
"rating": 3.7,
"reference": "CmReAAAAjJskNN69nw3gBVtqLpsX11Psr-QvK6cHPLhF-oDXAbYq7dwLn65b1svUJOLVnRgAbg4K3w7qCj9_hkXvx20q4YNR2714ZQQw89GyFGCtXAxonRh09_uvgK97DewsYRyUEhAczR_GzOvU0mmG1OZr0X3kGhQeJ1Vr3RSnI6VXyzh83W_LIcUK_g",
"types": [
"bar",
"restaurant",
"food",
"establishment"
]
},
Adding a little formatting to the pertinent part of the data:
sample data: {
"formatted_address": "8-12 Rue Boissy d'Anglas, 75008 Paris, France",
"geometry": {
"location": {
"lat": 48.868194,
"lng": 2.321596
}
},
"icon": "http://maps.gstatic.com/mapfiles/place_api/icons/bar-71.png",
"id": "560dd225114fd10997f75ee777bad84bcb40c529",
"name": "Buddha-Bar",
It is unclear what "sample data:" means as it is not quoted, it may be something added by the print statement (my guess) in which case it is not needed to access the components.
The name would be addresses as:
["name"]
The location is in lat/lon so there will be two accesses:
["geometry"]["location"]["lat"]
["geometry"]["location"]["lon"]
In the above the applicable language syntax must be applied, in Swift there will be some pain.
See json.org for information on JSON.
After some frustration and game of thrones. the messy solution was the one below.
an alternative may be api like
https://github.com/lingoer/SwiftyJSON
func searchDB(looking: String){
var errorOccurred:Bool = false
var urlString:String = "URLGOESHERE?q=\(looking)"
let url = NSURL(string: urlString)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if error != nil {
println(error)
errorOccurred = true
} else {
// println(response) //response from post
//processing data
let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
if let statusesArray = jsonObject as? NSArray{
println("********* LEVEL 1 *******")
println(statusesArray[0])
if let aStatus = statusesArray[0] as? NSDictionary{
println("********* LEVEL 2 *******")
println(aStatus)
if let geometry = aStatus["geometry"] as? NSDictionary{
println("********* LEVEL 3 *******")
println(geometry)
if let currLocation = geometry["location"] as? NSDictionary{
println("********* LEVEL 4 *******")
println(currLocation)
println(currLocation["lat"])
println(currLocation["lng"])
}
}
}
}
else {
errorOccurred = true
}
}//eo potential data
})
task.resume()
}//eom

Resources