How to get some data out of an array in swift? - swift

Here is my problem: I have an plist file, which have a simple strut:
root object is an array, and there are 2 sections in the array, each of them are dictionary including 2 pair key-value data:
and I'm going to create a tableView to show the datas, but I can't get the content out of the array :
here is how i declared my dataArray:
var plistArray = [AnyObject]()
can some one help me?

You need to properly cast at each level:
if let innerArray = plistArray[0] as? [AnyObject] {
if let dataDic = innerArray[indexPath.row] as? [String:String] {
if let imageName = dataDic["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}
}
}
But why are you using AnyObject when you know what the plist contains? Use proper types. You know it's an array of arrays of dictionaries with String keys and String values.
var plistArray = [[[String:String]]]()
Then all you need is:
if let imageName = plistArray[0][indexPath.row]["Pic"] {
cell?.imageView?.image = UIImage(named: imageName)
}

Related

Swift 3 - Access item key values by array index

Hi im trying to access the items in the legs array inside my plist
I want to be able to get the values for key = "title" from the legs array from this plist
I already have the method to get the values from the dictionary called abs which is the following code
let path = Bundle.main.path(forResource:"Exercise", ofType: "plist")
let dict:NSDictionary = NSDictionary(contentsOfFile: path!)!
if (dict.object(forKey: "levels") != nil) {
if let levelDict:[String : Any] = dict.object(forKey: "levels") as? [String : Any] {
for (key, value) in levelDict {
if ( key == "something") {
print(value)
}
}
}
}
However i have no idea how to access the legs array to get item titles
While reaching to the legs array which is of type [[String:String]] in your case with three elements and each index having two key pair values. You can loop over that index and get your values then iterate over to others.
let yourLegsArray:AnyObject = dict.object(forKey: "legs")! as AnyObject
then iterate over yourLegsArray and get the inside values of the Dict.
So I managed to find an answer to my original question
let path = Bundle.main.path(forResource: "Exercise", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)!
let levelArray:AnyObject = dict.object(forKey: "legs")! as AnyObject
if let nsArray:NSArray = levelArray as? NSArray{
var levelDict:AnyObject = nsArray[1] as AnyObject //currentLevel is an Int
//then finally I could get data from a dictionary in the array
let Title = levelDict["title"] as AnyObject? as! String
print(Title)
}
So now this will print the second item in legs array which is "leg 2"

Append Firebase Data into [String]() in Swift

I have data like below
I want to get the value of all objectIds and append it to a [String]() in Swift. Though when I use the append function, it first adds one, then two, and then three and so on. Below is the code I'm using right now.
var ObjectID: [String]?
override func viewDidLoad() {
super.viewDidLoad()
self.ObjectID = [];
let ref = Firebase(url:"https://blazing-heat-3676.firebaseio.com/results")
ref.queryOrderedByChild("objectId").queryLimitedToLast(201).observeEventType(.ChildAdded) { (snap: FDataSnapshot!) -> Void in
let objectId = snap.value["objectId"] as! String
self.ObjectID?.append(objectId)
print(self.ObjectID)
}
}
What modifications should I make for all objectIds to be in the array.
Firebase have no arrays but if the data looks like an array, Firebase clients will render it as an array. Therefore you can simply convert the result into an array and work with each individual object of this array.
let firebase = Firebase(url: "https://blazing-heat-3676.firebaseio.com/results")
firebase.observeSingleEventOfType(.Value) { (snapshot: FDataSnapshot!) -> Void in
guard let jsonArray: [JSON] = snapshot.value as? [JSON] else {
return
}
var objectIds: [String] = []
for json in jsonArray {
if let id = json["objectId"] as? String {
objectIds.append(id)
}
}
// Print result
print(objectIds)
}
Where JSON is
public typealias JSON = [String : AnyObject]
As an alternative solution - you can model this into query but you get the idea.
var myString: String = ""
ref.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
let name = child.value.objectForKey("ObjectId") as! String
myString += name
}
print(myString)
})
Also, you may want to re-think your keys (node names) as numeric sequential indexes are hard to work with. You should check into childByAutoId.
Also, Firebase does support arrays via NSArray however, there are usually much better alternatives.

Swift: Variable of Optional Dictionary inside Class: Shows Brackets in Output

I would like to make an Optional Dictionary Variable inside of a Class so that when I create an instance I don't HAVE to add that argument...
example
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0]){
}
}
var instance1 = Stuff(dictionary:["length":1.5])
var array: [Stuff] = [instance1, instance2]
let arraySet = (array[indexPath.row])
let X = arraySet.dictionary!
cell.Label.text = "\(X)"
This works but when i assign it to a cell.label.text the output shows Brackets...
"[length:1.5]"
How can i get rid of the brackets???
It's quite complicated to get rid of the brackets, because the key/value pair must be extracted out of the dictionary:
class Stuff {
var dictionary: [String: Double]?
init(dictionary: [String:Double]?=["":0.0]){
self.dictionary = dictionary
}
}
let instance = Stuff(dictionary:["length":1.5])
if let dict = instance.dictionary where dict.count > 0 {
let key = dict.keys.first!
let value = dict[key]!
label.text = "\(key) : \(value)"
}
If you create the dictionary with non-optional literals, consider to declare the variable dictionary as non-optional

How to point a Json array to a local image?

I'm new at this so sorry if this is basic but I'm trying to use an array in a json file and have it point to an image in my asset library but I'm running into problems. Its written as:
[
{
"image":"shrew",
},
]
Is it wrong to write it as a string? Do I need to have specific code to translate the string into my image names?
Thanks for any help you can offer!
Edit:
The error I'm getting is on line
TrackPic.image = image
"Use of unresolved identifier 'TrackPic'"
class QuizModel: NSObject {
func getQuestions() -> [Question] {
// Array of question objects
var questions:[Question] = [Question]()
// Get Json array of dictionaries
let jsonObjects:[NSDictionary] = self.getLocalJsonFile()
// Loop through each dictionary and assign values to our question objs
var index:Int
for index = 0; index < jsonObjects.count; index++ {
// Current JSON dict
let jsonDictionary:NSDictionary = jsonObjects[index]
// Create a question obj
var q:Question = Question()
let imageName = jsonDictionary["image"] as! String
let image = UIImage(named: imageName)
TrackPic.image = image
// Assign the values of each key value pair to the question object
q.image = jsonDictionary["image"] as! String
q.questionText = jsonDictionary["question"] as! String
q.answers = jsonDictionary["answers"] as! [String]
q.correctAnswerIndex = jsonDictionary["correctIndex"] as! Int
q.module = jsonDictionary["module"] as! Int
q.lesson = jsonDictionary["lesson"] as! Int
q.feedback = jsonDictionary["feedback"] as! String
// Add the question to the question array
questions.append(q)
}
// Return list of question objects
return questions
}
you first need to get the image name from the json like you did
let imageName = jsonDictionary["image"] as! String
(If you want to be certain that you are parsing your JSON correctly, be sure to write the imageName to the console)
Then you need to initialise a UIImage with UIImage(named: String) with you image name from json so
let image = UIImage(named : imageName)
Then you have your image, and you can put this on an UIImageView.
I suppose in your case, this would be
q.image = image
IF q is a UIImageView

Swift: Unable to get array values from singleton class

Hi I retrived value from JSON and stored in NSMutableArray. I have tried this like Singleton. I have used empty swift file for this. Datas successfully retrieved and stored in NSMutableArray which is already declared in mainViewController. Then, if I use that NSMutableArray value in mainViewController, it shows empty array.
My coding is below. Kindly guide me.
Empty Swift File
public class json_file{
var prod_Obj = product_mainVC()
class var shared: json_file
{
struct Static
{
static let instance: json_file = json_file()
}
return Static.instance
}
func dataFromJSON()
{
let url = NSURL(string: "http://........--...4900a20659")!
var data : NSData = NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMapped, error: nil)!
var dict: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
let dataArray = dict["data"] as [[String:AnyObject]] // The array of dictionaries
for object in dataArray {
let category_name = object["category_name"] as String
prod_Obj.ct_name_arr.addObject(category_name)
let category_child = object["category_child"] as [[String:AnyObject]]
for child in category_child {
let sub_category_name = child["sub_category_name"] as String
prod_Obj.sub_ct_name_arr.addObject(sub_category_name)
}
}
println(prod_Obj.ct_name_arr) //Here value is Getting
println(prod_Obj.sub_ct_name_arr) //Here value is Getting
}
}
viewDidLoad
{
json_file.shared.dataFromJSON()
println(ct_name_arr) //Prints Empty Array [Intially Declared as NSMutableArray]
println(sub_ct_name_arr) //Prints Empty Array [Intially Declared as NSMutableArray]
}
I was trying understand the problem, but I can't see the product_mainVC. Because this I remake your class with little modifications.
class JsonFile
{
private(set) var categoryNames:[String];
private(set) var subCategoryNames:[String];
class let shared:JsonFile = JsonFile();
private init()
{
self.categoryNames = [];
self.subCategoryNames = [];
}
func dataFromJson()
{
let url = NSURL(string: "http://........--...4900a20659")!
if let data : NSData = NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMapped, error: nil)
{
if let dict: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary
{
if let dataArray = dict["data"] as? [[String:AnyObject]] // The array of dictionaries
{
for object in dataArray {
let category_id = object["category_id"] as Int
let category_name = object["category_name"] as String
categoryNames.append(category_name);
let category_child = object["category_child"] as [[String:AnyObject]]
for child in category_child {
let sub_category_id = child["sub_category_id"] as Int
let sub_category_name = child["sub_category_name"] as String
subCategoryNames.append(sub_category_name);
}
}
}
}
}
println(categoryNames);
println(subCategoryNames);
}
}
I did
Modify your way to do Singleton to a safe and more simple mode, create the arrays categoryNames and subCategoryNames internal in class because this is better to manipulate, and protect your fetch data to safe from possibles crash.
Implementation
JsonFile.shared.dataFromJson();
println("count categoryNames");
println(JsonFile.shared.categoryNames.count);
println("count subCategoryNames");
println(JsonFile.shared.subCategoryNames.count);
You need think about
This code is sync, and because this if you have a big data or request slow, the main thread from your application will freeze waiting return and it is bad for your user. Think if is necessary be sync.
let category_id = object["category_id"] as Int is never used. Why do you stay with this in code?