How to use NSDictionaries values in BarGraph generation - ios

Need a little help please, I am reasonably new to the iOS developing and current stuck in a small problem.
I am trying to pass the values that I have got from JSON file into another method so I can generate the barGraph, but I am having problem to pass it as an String Array.
Here is the view controller class, I am trying to figure out a way to complete it, please also see the 2 classes that I have created, I can confirm the values are all there.
View Controller Class -
import UIKit
import Charts
class ViewController: UIViewController, ChartViewDelegate {
#IBOutlet weak var barChartView: BarChartView!
let model:JsonModel = JsonModel()
var data:[Data] = [Data]()
var censusYear:[String]! = []
var currentData:Data = Data()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
barChartView.delegate = self
// Kick off the data gathering
self.data = self.model.getData()
// Kick off the graph generation
setChart(<#T##[String]#>, values: <#T##[Double]#>)
}
func setChart(dataPoints: [String], values: [Double]) {
barChartView.noDataTextDescription = " You need to provide data for the chart"
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Population")
let chartData = BarChartData(xVals: censusYear, dataSet: chartDataSet)
barChartView.data = chartData
barChartView.descriptionText = "This is a test"
chartDataSet.colors = ChartColorTemplates.colorful()
barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .EaseInBounce)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Data Class -
class Data: NSObject {
var area:String = ""
var censusYear:String = ""
var sex:String = ""
var population:Double = 0
}
JSON Data Model Class -
class JsonModel: NSObject {
func getData() -> [Data] {
// Get array of data objects
var data:[Data] = [Data]()
// Get JSON array of dictionaries
let jsonObjects:[NSDictionary] = self.getLocalFile()
// Loop through each dictionary and assign values to the data object parse JSON File
var index:Int
for index = 0; index < jsonObjects.count; index++ {
// Current JSON Dict
let jsonDictionary:NSDictionary = jsonObjects[index]
// Create a Data object
let d:Data = Data()
// Assign value to each key value pair to the data object
d.area = jsonDictionary["area"] as! String
d.censusYear = jsonDictionary["census year"] as! String
d.sex = jsonDictionary["sex"] as! String
d.population = jsonDictionary["population"] as! Double
// Add the data into data array
data.append(d)
}
// Return list of data object
return data
}
func getLocalFile() -> [NSDictionary] {
// Get an NSURL object pointing to the JSON filed in the app bundle
let appBundlePath:String? = NSBundle.mainBundle().pathForResource("sample3", ofType: "json")
// TODO: Use optional binding or guard to check if path exisits
if let actualBundlePath = appBundlePath {
// Path exists
let urlPath:NSURL = NSURL(fileURLWithPath: actualBundlePath)
let jsonData:NSData? = NSData(contentsOfURL: urlPath)
if let actualJsonData = jsonData {
// NSData exists, use the NSJSONSerialization classes to parse the data and create the dictionaries
do {
let arrayOfDictionaries:[NSDictionary] = try NSJSONSerialization.JSONObjectWithData(actualJsonData, options: NSJSONReadingOptions.MutableContainers) as! [NSDictionary]
return arrayOfDictionaries
}
catch {
// There was an error parsing the json file
}
}
else {
// NSData doesnt exist
}
}
else {
// Path to json file in the app bundle doesnt exist
}
// Return an empty array
return [NSDictionary]()
}

Related

Saving array to Core Data

I've created two arrays (imgUrl and imgTitle). I want to save these array values in Core Data. I tried like below. However, it is not successful.
//Mark:- Method to save data in local data base(CoreData)
func saveDataInLocal(imageUrl: [String], imageTitle: [String]){
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let contactEntity = NSEntityDescription.entity(forEntityName: "Photos", in: context)
let newContact = NSManagedObject(entity: contactEntity!, insertInto: context)
for eachValue in imageTitle{
newContact.setValue(eachValue, forKey: "imgTitle")
}
for eachValue in imageUrl{
newContact.setValue(eachValue, forKey: "imgUrl")
}
do {
try context.save()
fetchData()
} catch {
print("Failed saving")
}
}
XcmodelID is shown in image.
In these two arrays one is image title and another one image URL.
Fetching I'm doing like below.
//Mark:- Method to fetch data from local database(CoreData)
func fetchData(){
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Photos")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
imgTitleNew.append(data.value(forKey: "imgTitle") as! String)
imgUrlNew.append(data.value(forKey: "imgUrl") as! String)
}
} catch {
print("Failed")
}
DispatchQueue.main.async {
self.myCollectionView.reloadData()
}
}
Can somebody suggest how to save the array in Core Data?
Array data displayed below.
var imgUrl = [String]() //contains urls in array
var imgTitle = [String]() //contains titles in array
A simple solution is to save both arrays joined with tab (or other unique) characters and use computed properties for the conversion
Assuming the Core Data properties are declared as
#NSManaged public var imageURL: String
#NSManaged public var imageTitle: String
Add these two computed properties
var imageURLArray : [String] {
get { return imageURL.components(separatedBy: "\t") }
set { imageURL = newValue.joined(separator: "\t") }
}
var imageTitleArray : [String] {
get { return imageTitle.components(separatedBy: "\t") }
set { imageTitle = newValue.joined(separator: "\t") }
}

Converting all Realm Objects to Dictionary at once

I am using Realm and I have an extension that I use to convert my Realm model into a Dictionary , but I do not know how to convert all my Realm models at once. I want to know how do I convert all the realm Objects at once and in one place, so that I can send that dictionary to a API.
Here are my Realm Object Models and the extension I use:
class OrderItemList: Object {
dynamic var dateCreated = NSDate()
let orderItems = List<OrderItem>()
}
class OrderItem: Object {
dynamic var name = " "
dynamic var amount = 0
dynamic var internalUnique = Int()
dynamic var isCompleted = false
}
Extension:
extension Object {
func toDictionary() -> NSDictionary {
let properties = self.objectSchema.properties.map { $0.name }
let dictionary = self.dictionaryWithValuesForKeys(properties)
let mutabledic = NSMutableDictionary()
mutabledic.setValuesForKeysWithDictionary(dictionary)
for prop in self.objectSchema.properties as [Property]! {
// find lists
if let nestedObject = self[prop.name] as? Object {
mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
} else if let nestedListObject = self[prop.name] as? ListBase {
var objects = [AnyObject]()
for index in 0..<nestedListObject._rlmArray.count {
let object = nestedListObject._rlmArray[index] as AnyObject
objects.append(object.toDictionary())
}
mutabledic.setObject(objects, forKey: prop.name)
}
}
return mutabledic
}
}
Unfortunately, there's no magic bullet for converting a batch of Realm objects to a dictionary. You'll need to query for the objects you want, and then loop through each one to produce a serialized version of it.
let realm = try! Realm()
var objectDictionaries = [NSDictionary]()
let allObjects = realm.objects(OrderItemList.self)
for object in allObjects {
let dictionary = object.toDictionary()
objectDictionaries.append(dictionary)
}
I hope that answered your question!

Create an Array of Objects with Firebase Async Dictionary Download (Swift)

I'm new to Swift. I have been having trouble downloading Firebase dictionaries and turning them into an array of objects.
What am I doing wrong with the syntax below? I've spent the last two days unsuccessfully trying to figure this out. The following gives me an index out of range error. Is this because the Firebase Dictionary hasn't finished downloading yet or is my for in loop sytax flawed? Perhaps both? Thanks.
// Array of Location Objects
var locationsArray:[Location] = [Location]()
var ref = Firebase(url: "<MYFIREBASEURL>")
var dictionaryOfRecommendations:[NSDictionary] = [NSDictionary]()
var currentlyConstructingLocation:Location = Location()
func getLocationData() {
let titleRef = self.ref.childByAppendingPath("events")
titleRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
var tempDict = [NSDictionary]()
for item in snapshot.children {
let child = item as! FDataSnapshot
let dict = child.value as! NSDictionary
tempDict.append(dict)
}
self.dictionaryOfRecommendations = tempDict
})
// Parse data from Firebase
// Loop through each dictionary and assign values to location object
var index:Int
for index in 0...dictionaryOfRecommendations.count {
// Current Json dictionary
let jsonDictionary:NSDictionary = self.dictionaryOfRecommendations[index]
self.currentlyConstructingLocation.title = jsonDictionary["title"] as! String!
self.currentlyConstructingLocation.locationsLatitudeArray = jsonDictionary["latitude"] as! Double
self.currentlyConstructingLocation.locationsLongitudeArray = jsonDictionary["longitude"] as! Double
// Append to Locations Array and start new Location
self.locationsArray.append(currentlyConstructingLocation)
self.currentlyConstructingLocation = Location()
}
// Notify the MainViewController that the Locations are ready.
...
}
Here's the updated correct code for the question above based on Jay's helpful guidance:
// Model to download location data for events.
//Firebase reference
var ref = Firebase(url: "<MYFIREBASEURL")
var locationsArray:[Location] = [Location]()
var dictionaryOfRecommendations:[NSDictionary] = [NSDictionary]()
var currentlyConstructingLocation:Location = Location()
func getLocationData() {
let titleRef = self.ref.childByAppendingPath("events")
titleRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
var tempDict = [NSDictionary]()
for item in snapshot.children {
let child = item as! FDataSnapshot
let dict = child.value as! NSDictionary
tempDict.append(dict)
}
self.dictionaryOfRecommendations = tempDict
self.ParseFirebaseData()
})
}
func ParseFirebaseData() {
// Parse data from Firebase
// Loop through each dictionary and assign values to location object
var index:Int
for index in 0...dictionaryOfRecommendations.count - 1 {
// Current Json dictionary
let jsonDictionary:NSDictionary = self.dictionaryOfRecommendations[index]
self.currentlyConstructingLocation.title = jsonDictionary["title"] as! String!
self.currentlyConstructingLocation.locationsLatitudeArray = jsonDictionary["latitude"] as! Double
self.currentlyConstructingLocation.locationsLongitudeArray = jsonDictionary["longitude"] as! Double
// Append to Locations Array and start new Location
self.locationsArray.append(currentlyConstructingLocation)
self.currentlyConstructingLocation = Location()
}
}

how to remove Duplicate values from Dict in swift 2.0

Hi I just want remove repeated objects should be removed in dictionary I am populating it in tableView
Here my sample code in 'CellForRowAtIndexPath'
controller.titleName = dict["itemName"] as? String
my output:
{
itemName = test;
},
{
itemName = funny;
},
{
itemName = vv;
},
{
itemName = hhh;
},
{
itemName = west;
}
First, i think thing you are using array to make dict so before load tableview/collectionview delete all replicated object from your array.
There is one option you have to create NSSet from NSArray so in NSSet all replicated object automatically removed . and then from NSSet you have to create NSArray.
convert set from array as follow
var set = NSSet(array: myarray)
To convert array for set
var newarry = set.allObjects as NSArray
Just try this
let uniqueArr = Array(Set(dict.values))
For your question I have tried separately and I got the answer
var arr = [AnyObject]()
var arrAppend = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let array = ["one", "one", "two", "two", "three", "three"]
let uniqueValue = Array(Set(array))
print("The unique value is - \(uniqueValue)")
let dictTest = ["itemName":"test"]
let dictFunny = ["itemName":"funny"]
let dictVVV = ["itemName":"vvv"]
let dictHHH = ["itemName":"hhh"]
let dictWest = ["itemName":"west"]
let dictTT = ["itemName":"tt"]
let dictWest1 = ["itemName":"west"]
arr.append(dictWest1)
arr.append(dictTest)
arr.append(dictVVV)
arr.append(dictTT)
arr.append(dictWest)
arr.append(dictFunny)
arr.append(dictHHH)
print("Array Response: \(arr)")
for keyValue in arr as Array
{
let getDictValueFromArray = keyValue["itemName"] as! String
arrAppend.append(getDictValueFromArray)
}
let unique = Array(Set(arrAppend))
print("the result is-\(unique)")
}
The Output for unique is
the result is-["funny", "test", "west", "vvv", "hhh", "tt"]

Saving a Dictionary to Core Data

My app parses podcast RSS feeds. I use 2 entities: Podcasts (to hold podcast-related data) and Episodes (Episodes data like summaries etc). After parsing a feed, I store the list of episodes in an Array called "episodesToDisplay". When a user subscribes to a podcast, I want to save the data held by that array in Core Data. Here is my code which throws an error on the annotated line below:
class Podcasts: UITableViewController {
var currentPodcast: Podcasts!
override func viewDidLoad() {
super.viewDidLoad()
let podcastsEntity = NSEntityDescription.entityForName("Podcasts", inManagedObjectContext: self.managedContext)
let podcastsFetch = NSFetchRequest(entityName: "Podcasts")
var error: NSError?
let result = self.managedContext.executeFetchRequest(podcastsFetch, error: &error) as [Podcasts]?
if let resu = result {
println("res is \(resu.count)")
self.currentPodcast = resu[0] as Podcasts
} else {
println("did not work")
}
}
#IBAction func subscribe(sender: AnyObject) {
for dict: AnyObject in episodesToDisplay {
let episodesEntity = NSEntityDescription.entityForName("Episodes", inManagedObjectContext: self.managedContext)
let episodesToSave = Episodes(entity: episodesEntity!, insertIntoManagedObjectContext: self.managedContext)
var episodes = currentPodcast.episode.mutableCopy() as NSMutableOrderedSet
let btDict = dict as NSDictionary <---------------- Crash
episodesToSave.title = btDict["title"] as String
episodesToSave.summary = btDict["summary"] as String
episodesToSave.link = btDict["link"] as String
episodes.addObject(episodesToSave)
currentPodcast.episode = episodes.copy() as NSOrderedSet
}
// Save
var error:NSError?
if !self.managedContext.save(&error) {
println("could not save \(error)")
}
}
Any ideas please?
The error indicates that your array doesn't contain NSDictionary objects - that is why you get dynamic cast exception when you try and access an element as an NSDictionary.
From your comment it seems that your array actually contains MWFeedItem objects, so all you need to do is change your code to use that object type and then you can access the properties of the MWFeedItem -
#IBAction func subscribe(sender: AnyObject) {
for item: MWFeedItem in episodesToDisplay {
let episodesEntity = NSEntityDescription.entityForName("Episodes", inManagedObjectContext: self.managedContext)
let episodesToSave = Episodes(entity: episodesEntity!, insertIntoManagedObjectContext: self.managedContext)
var episodes = currentPodcast.episode.mutableCopy() as NSMutableOrderedSet
episodesToSave.title = item.title
episodesToSave.summary = item.summary
episodesToSave.link = item.link
episodes.addObject(episodesToSave)
currentPodcast.episode = episodes.copy() as NSOrderedSet
}

Resources