ParseJson data from array located in another array - ios

Hello I'm trying to Parse parseJson data from an array. My problem is that I do not know how to access my response, because it is an array located in another array.
This is my response:
{
"finalResult": [
[
{
"Id":2,"latitude":"49.993820099043","longitude":"14.660662520439","usrId":2,"timeCreated":"2016-08-06 18:31:32"
}
],
[
{
"Id":3,"latitude":"49.993900553360","longitude":"14.660832398337","usrId":2,"timeCreated":"2016-08-06 18:29:37"
}
]
]
}
This is part of code I need help with:
if let parseJson = json {
if let events = parseJson["finalResult"] as? [AnyObject] {
for event in events {
for single in (event as? [AnyObject])! {
let Id = single["Id"] as! String
let latitude = single["latitude"] as! String
let longitude = single["longitude"] as! String
let usrId = single["usrId"] as! String
print(id)
print(latitude)
print(longitude)
print(usrId)
}
}
}
}

for event in events {
if let customObjects = event as? [AnyObject] {
for customObject in customObjects {
let Id = customObject["Id"] as! String
let latitude = customObject["latitude"] as! String
let longitude = customObject["longitude"] as! String
let usrId = customObject["usrId"] as! String
print(id)
print(latitude)
print(longitude)
print(usrId)
}
}
}

Related

Managing encapsulated data in closure

Newbie here.Using Google API Nearby Search. I have problem sending encapsulated data into closure, already populated table with vicinity info, but when i try to send placeID info into closure to get Details, it gives me nil.
Here i get placeID and vicinity, and afterwards populate tableView with places array. Class Place is in separate swift file, function downloadPlaceID is inside ViewController.
class Place {
var placeId: String!
var vicinity: String!
var _placeId: String {
if placeId == nil {
placeId = ""
}
return placeId
}
var _vicinity: String {
if vicinity == nil {
vicinity = ""
}
return vicinity
}
init( place: [String:Any]) {
if let ids = place["id"] as? String {
self.placeId = ids
}
if let vicinities = place["vicinity"] as? String {
self.vicinity = vicinities
}
}
}
func downloadPlaceID (completed: #escaping DownloadComplete) {
let placeURL = URL(string: nearbyURL)
Alamofire.request(placeURL!).responseJSON { (response) in
let result = response.result
if let dictionary = result.value as? [String:Any] {
if let results = dictionary["results"] as? [[String:Any]] {
if let status = dictionary["status"] as? String {
if status == "OK" {
for obj in results {
place = Place(place: obj)
// here i get all the placeID's
places.append(place)
}
}
}
}
}
completed()
}
}
Then i try to get details, into which I put placeID:
func downloadDetails( input: String, completed: DownloadComplete) {
let details = "\(detailsBaseURL)\(detailsPlaceId)\(input)\(detailsKey)\(detailsSearchAPIKey)"
print(placeID)
Alamofire.request(details).responseJSON { response in
let result = response.result
if let dictionary = result.value as? [String:Any] {
if let result = dictionary["result"] as? [String:Any] {
if let phoneNumber = result["formatted_phone_number"] as? String {
self.phone = phoneNumber
print(self.phone!)
}
if let geometry = result["geometry"] as? [String:Any] {
if let location = geometry["location"] as? [String:Any] {
if let latitude = location["lat"] as? Double {
self.lat = latitude
print(self.lat!)
}
if let longitude = location["lng"] as? Double {
self.lng = longitude
print(self.lng!)
}
}
}
if let openingHours = result["opening_hours"] as? [String:Any] {
if let openNow = openingHours["open_now"] as? Bool {
self.workHours = openNow
print(self.workHours!)
}
}
}
}
}
}
Here is code inside viewDidLoad that i'm trying to use to get details.
override func viewDidLoad() {
super.viewDidLoad()
downloadPlaceID {
detail.downloadDetails(input: place.placeId, completed: {
})
}
}
It should be "place_id" instead of "id"
class Place {
var placeId: String!
var vicinity: String!
var _placeId: String {
if placeId == nil {
placeId = ""
}
return placeId
}
var _vicinity: String {
if vicinity == nil {
vicinity = ""
}
return vicinity
}
init( place: [String:Any]) {
if let ids = place["place_id"] as? String {
self.placeId = ids
}
if let vicinities = place["vicinity"] as? String {
self.vicinity = vicinities
}
}
}

parse json in UICollectionViewCell in swift

I want to parse JSON in UICollectionviewCell. I have a collectionViewController with two UICollectionviewCell. In collectionViewController first cell made to background scrolling and in the second I want to parse JSON. There is no error in the code, this is my JSON code.
var oCategoryFilter: CategoryFilter? {
didSet {
if let name = oCategoryFilter?.totalItem {
totalItemLabel.text = name
}
appsCollectionView.reloadData()
}
}
var arrProduct: [Product]?
func getPropductListByCategory(){
let category_id:String;
category_id = "21"
let url = URL(string: UtilityController.BASE_URL+"/products/"+category_id)
URLSession.shared.dataTask(with:url!) { (urlContent, response, error) in
if error != nil {
print(error)
}
else {
do {
let json = try JSONSerialization.jsonObject(with: urlContent!) as! [String:Any]
print(json)
let items = json["categories"] as? [[String: Any]] ?? []
items.forEach { item in
let oProduct = Product()
//oProduct.id = item["id"] as? String
oProduct.image = item["image"] as? String
oProduct.name = item["name"] as? String
oProduct.ar_name = item["ar_name"] as? String
//oProduct.description = item["description"] as? String
oProduct.ar_description = item["ar_description"] as? String
oProduct.price = item["price"] as? String
oProduct.quantity = item["quantity"] as? String
oProduct.is_featured = item["is_featured"] as? String
oProduct.seller_id = item["seller_id"] as? String
oProduct.payment_required = item["payment_required"] as? String
oProduct.is_editors_choice = item["is_editors_choice"] as? String
oProduct.created_at = item["created_at"] as? String
oProduct.updated_at = item["updated_at"] as? String
self.arrProduct?.append(oProduct)
}
print(url)
} catch let error as NSError {
print(error)
}
}
DispatchQueue.main.async(execute: {
self.appsCollectionView.reloadData()
})
}.resume()
}
When are you calling your functions ? You should call the method in the CollectionView, when it is loading every cell, but doing that is really bad, because each time you will scroll or reload your CollectionView it will parse again.
You should parse in a special class, call by the collection view and this last send the parse object to the cell.

Convert JSON nested objects

I am getting the following JSON from Foursquare API and I have been struggling with extracting the data:
{
"meta":{
"code":200,
"requestId":"58122e59498e5506a1b23580"
},
"response":{
"venues":[
{
"id":"4d56c381a747b60cd4a12c2b",
"name":"Sports Circle",
"contact":{},
"location":{
"lat":31.9,
"lng":35.9,
"labeledLatLngs":[
{
"label":"display",
"lat":31.9,
"lng":35.90
}
],
],
"confident":true
}
}
}
I want to get the name in venues in addition to the lat and lng values. I have tried this so far but it gets out of the second if statement at JVenues because it is nil:
func parseData (JSONData: Data){
do {
var readableJson = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! [String:AnyObject]
if let JResponse = readableJson ["response"] as? [String:AnyObject] {
if let JVenues = JResponse["venues"] as? [String:AnyObject]{
if let JName = JVenues["name"] as? String{
NSLog(JName)
}
}
}
} catch {
print(error)
}
}
This is what the other answers are getting at. Will probably make more sense if you can see it all laid out...
if let JResponse = readableJson ["response"] as? [String : AnyObject] {
if let JVenues = JResponse["venues"] as? [[String : AnyObject]] {
if let JName = JVenues.first?["name"] as? String {
NSLog(JName)
}
}
}
Note this only gets the FIRST name in the array of venues.
EDIT:
I prefer something like this. Define a struct and convert your dictionaries to the struct:
struct Venue {
var name: String?
var venueId: String?
init(_ venueDictionary: [String : AnyObject]) {
self.name = venueDictionary["name"] as? String
self.venueId = venueDictionary["id"] as? String
}
}
In your class create a property such as:
var venues = [Venue]()
From your JSON map the dictionaries to the venue array. I renamed variables that start with a capital for convention.
if let response = readableJson ["response"] as? [String : AnyObject] {
if let responseVenues = response["venues"] as? [[String : AnyObject]] {
self.venues = responseVenues.map({ Venue($0)) })
}
}
Use anywhere in your class like:
let venue = self.venues.first
print(venue?.name)
Or:
if let venue = self.venues.find({ $0.name == "Sports Circle" }) {
print("found venue with id \(venue.venueId)")
}

Swift Firebase Access child snapshot data

I am currently trying to access data from a child snapshot in Swift. Here is my code that I have (which worked before the Swift 3/Firebase update):
if let achievements = snapshot1.childSnapshotForPath("Achievements").children.allObjects as? [FIRDataSnapshot] {
if achievements.count != 0 {
if let val = achievements[0].value!["somevalue"] as? Int {
self.dict["somevalue"] = val
}
}
So what I am trying to do here, is to create a variable of a child snapshot (achievements), and access child snapshot data from it. The achievements[0] will simply return the very first value. However, this doesn't seem to work. How should I approach this?
I am currently doing this inside a snapshot already (of 'observeType:.ChildAdded')
My Firebase DB looks like this:
Achievements{
randomId1 {
somevalue : somevalue
}
randomId2 {
somevalue2 : somevalue2
}
}
Updated code:
func loadData() {
ref.child("Players").observe(FIRDataEventType.childAdded) { (snapshot:FIRDataSnapshot) in
if let value = snapshot.value as? [String:AnyObject], let username = value["Username"] as? String {
}
if let value = snapshot.value as? [String:AnyObject], let ranking = value["Rank"] as? String {
}
if let childSnapshot = snapshot.childSnapshot(forPath: "Achievements").children.allObjects as? [FIRDataSnapshot] {
if childSnapshot.count != 0 {
if let achievement1 = childSnapshot[0].value!["Rookie"] as? String {
print(achievement1)
}
}
}
}
}
JSON Tree:
Players {
PlayerID {
Username
Rank
Achievements {
Rookie: yes
}
}
Try :-
if let childSnapshot = snapshot.childSnapshot(forPath: "Achievements") as? FIRDataSnapshot{
if let achievementDictionary = childSnapshot.value as? [String:AnyObject] , achievementDictionary.count > 0{
if let achieveMedal = achievementDictionary["Rookie"] as? String {
print(achieveMedal)
}
}
}

parse nested JSON attributes in swift

Having trouble which is probably so minor but my searches turn up nothing. I have a json model as follows :
//quick syntax to give you an idea of the model
{user:
{"name": "",
"password": "",
"medium" : {
{"title":"",
{"description":""}}}
I'm getting the above data model from a GET request to user and it returns all the info above but when i try to parse the "medium" information such as "title" & "description" I'm having no luck. I get these responses in Xcode that say
"Value of object 'AnyObject' not unwrapped, did you mean to use ! or ?"
and then when i click on the round red Xcode message to fix it it places !s and ?s everywhere but the error remains. Here is my parse method which worked perfectly fine when I was parsing only from the "medium". Any idea what I'm doing wrong?
a portion of the parse method where i get the same error for each attribute:
all lines with the same error indicated by *
// Parse JSON data
let jsonMedium = jsonResult?["user"] as! [AnyObject] //media where user is
for jsonMedia in jsonMedium {
let media = Media()
*media.title = jsonMedia["medium"]["title"] as! String
*media.description = jsonMedia["medium"]["description"] as! String
*media.category = jsonMedia["medium"]["category"] as! String
*media.image = jsonMedia["medium"]["image"] as! String
*if let IDer = jsonMedia["medium"]["id"] as? Int{
var stringIder = String(IDer)
media.identifierString = stringIder
}
Still no luck with anything. I don't understand why it works with regular JSON but Xcode won't accept anything when I try to obtain nested. All of your help has been appreciated. In the meantime here's the full method if it helps any further
func parseJsonData(data: NSData) -> [Media] {
var medium = [Media]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Parse JSON data
let jsonMedium = jsonResult?["media"] as! [AnyObject]
for jsonMedia in jsonMedium {
let media = Media()
media.title = jsonMedia["medium"]["title"] as! String
media.description = jsonMedia["medium"]["description"] as! String
media.category = jsonMedia["medium"]["category"] as! String
media.image = jsonMedia["medium"]["image"] as! String
if let IDer = jsonMedia["medium"]["id"] as? Int{
var stringIder = String(IDer)
media.identifierString = stringIder
}
medium.append(media)
}
} catch {
print(error)
}
return medium
}
let json = [
"user" : [
"name" : "My Name",
"password" : "My Password",
"medium" : [
"title" : "My Title",
"description" : "My Description"
]
]
]
if let userJson = json["user"] as? [String : AnyObject] {
if let name = userJson["name"] as? String {
print("name: \(name)")
}
if let password = userJson["password"] as? String {
print("password: \(password)")
}
if let mediumJson = userJson["medium"] as? [String : AnyObject] {
if let title = mediumJson["title"] as? String {
print("title: \(title)")
}
if let description = mediumJson["description"] as? String {
print("description: \(description)")
}
}
}
Maybe it helps
let request : ASIFormDataRequest = ...your request
if request.responseString() != nil {
var jsonResponse : Dictionary<String, AnyObject>?
do{
jsonResponse = try NSJSONSerialization.JSONObjectWithData(request.responseData(), options: NSJSONReadingOptions.AllowFragments) as? Dictionary<String, AnyObject>
} catch _ {
//some error
}
}
FIXED IT! Took an entire day of deep thought and google/youtube/stack/brainstorming and your help but it was one changed line that got the whole thing going
// Parse JSON data
let jsonMedium = jsonResult?["user"]!["medium"] as? [AnyObject]
for jsonMedia in jsonMedium! {
let media = Media()
media.title = jsonMedia["title"] as! String
media.description = jsonMedia["description"] as! String
instead of :
let jsonMedium = jsonResult?["user"] as! [AnyObject] //media where user is
for jsonMedia in jsonMedium {
let media = Media()
*media.title = jsonMedia["medium"]["title"] as! String
*media.description = jsonMedia["medium"]["description"] as! String

Resources