I am getting values from and Array[String:Any] type array in a for loop but it is getting crashed when going on first line in for loop .
Actually I have created an array (Array[String:Any]) Type and now I am getting all the values of this array to show on tableview but it is getting crash in for loop.
var ticketArray = [Any]()
var addTypeTicket = [String:Any]()
var imagesArray = [Any]()
var imagesFinal = [String:Any]()
let ticketDetails = ["ticketName":txtTicketName.text!,
"numberOfTicketOnSale":txtFldTotalQuantityofTicket.text!,
"ticketPrice":txtFldPriceofTicket.text!,
"messageForTicketBuyers":txtviewMessage.text!,
"ticketGroupName":txtFldGroupName.text!] as [String : Any]
ticketArray.append(ticketDetails)
print(ticketArray)
addTypeTicket["addTypeTicket"] = ticketArray
print(addTypeTicket)
viewShadowTicket.isHidden = true
viewForMainTicketAlert.isHidden = true
for alltickets in addTypeTicket {
let ticketName = (alltickets as AnyObject).object(forKey: "ticketName") as! String
let Quantity = (alltickets as AnyObject).object(forKey: "numberOfTicketOnSale") as! String
let ticketPrice = (alltickets as AnyObject).object(forKey: "ticketPrice") as! String
let arr = structTickets(ticketName: ticketName, numberOfTicketOnSale: Quantity, ticketPrice: ticketPrice)
self.arrayTickets.append(arr)
}
self.tableview.reloadData()
tableview.isHidden = false
I just want to get values in for loop .
If you are not using ticketArray anywhere else then there is not need to add data to that array. You can simply add data to addTypeTicket dictionary by:
addTypeTicket["addTypeTicket"] = ticketDetails
Then you can fetch the data like this:
if let addTypeTicketData = addTypeTicket["addTypeTicket"] as? [String: String] {
let ticketName = addTypeTicketData["ticketName"]
let quantity = addTypeTicketData["numberOfTicketOnSale"]
let ticketPrice = addTypeTicketData["ticketPrice"]
let arr = structTickets(ticketName: ticketName, numberOfTicketOnSale: quantity, ticketPrice: ticketPrice)
self.arrayTickets.append(arr)
}
And use arrayTickets for tableView's numberOfRowsInSection.
Related
I try to parse and assign data, which I am becoming from Firebase
The structure in Firebase looks like this:
I try to fetch data from database and assign it to instance of class Meal:
ref = Database.database().reference()
databaseHandle = ref.child("Meal").observe(.value, with: { (snapshot) in
var downloadedName : String!
var downloadedPhoto : String!
var downloadedRating : Int!
var downloadedSteps : Array <String>!
var downloadedIngredients : [Dictionary <String, String>]!
print(snapshot.value)
if let dict = snapshot.value as? Dictionary<String, Any>{
print("VALUES!!!")
for key in dict.keys {
if let values = dict[key] as? Dictionary<String, Any> {
print(values)
if let name = values["name"] as? String{
downloadedName = name
}
if let photo = values["photo"] as? String{
downloadedPhoto = photo
}
if let rating = values["rating"] as? Int{
downloadedRating = rating
}
if let steps = values["steps"] as? Array<String>{
downloadedSteps = steps
}
if let ingredients = values["ingredients"] as? [Dictionary <String, String>]{
downloadedIngredients = ingredients
}
let meal = Meal(name: downloadedName, photo: UIImage(named: downloadedPhoto), rating: downloadedRating, steps: downloadedSteps, ingredients: downloadedIngredients)
self.meals.append(meal!);
}
}
The Meal class itself looks like this:
class Meal {
var name: String
var photo: UIImage?
var rating: Int
var steps: Array<String>
var ingredients: [Dictionary<String, String>]}
I get the first print - the whole data, so the connection with DB is OK, but as i try to assign it - nothing happens, no errors, no data (the second print with message VALUES!!! is not shown at all, what am I doing wrong?
Here is also what I get by first print
Optional(<__NSArrayM 0x600002fdaa60>(
{
ingredients = (
{
amount = 100;
ingredient = milk;
measurement = ml;
},
{
amount = 120;
ingredient = milk;
measurement = ml;
}
);
name = "Caprese Salad";
photo = meal1;
rating = 4;
steps = (
test1,
test11
);
},
{
ingredients = (
{
amount = 100;
ingredient = milk;
measurement = ml;
},
{
amount = 120;
ingredient = milk;
measurement = ml;
}
);
name = "Chicken and Potatoes";
photo = meal2;
rating = 3;
steps = (
test2,
test22
);
},
{
ingredients = (
{
amount = 100;
ingredient = milk;
measurement = ml;
},
{
amount = 120;
ingredient = milk;
measurement = ml;
}
);
name = "Pasta with Meatballs";
photo = meal3;
rating = 2;
steps = (
test3,
test33
);
}
)
)
So, I assume, I retrieve the data in the false way at some point, how could i fix it?
You have:
print(snapshot.value)
if let dict = snapshot.value as? Dictionary<String, Any>{
print("VALUES!!!")
....
}
You say that print(snapshot.value) is called but not print("VALUES!!!").
Well, that means that snapshot.value or it isn't a Dictionary which keys are String objects and values are of type Any.
Now, let's see the output of snapshot.value:
Optional(<__NSArrayM 0x600002fdaa60> ...
NSArrayM => NSMutableArray, so snapshot.value is an Array, not a Dictionary. Of course then the as? Dictionary will fail!
So you need to treat it as an Array.
Quickly written:
if let array = snapshot.value as? [[String: Any]] {
for aValue in array {
let name = aValue["name"] as? String ?? "unnamed"
let photoName = aValue["photo"] as? String ?? "noPhoto"
let rating = aValue["rating"] as? Int ?? 0
let steps = aValue["steps"] as? [String] ?? []
let ingredients = aValue["ingredients"] as? [[String: String]] ?? [:]
let meal = Meal(name: name, photo: UIImage(named: photoName), rating: rating, steps: steps, ingredients: ingredients)
self.meals.append(meal)
}
}
What could also been wrong with your approach:
var downloadedName : String!
loop {
if let name = values["name"] as? String {
downloadedName = name
}
let meal = Meal(name: downloadedName, ...)
}
Well, if for the second value you didn't have a name (either because it's not a String or because the value doesn't exist), you downloadedName would have the value of the first one, but the rest of the values of the second one.
I used the approach:
let name = aValue["name"] as? String ?? "unnamed"
Meaning, that if it's nil, it gets a default value.
But you could decide to accept only valid one, by a guard let or if let potentially on all the subvalues.
For instance:
if let name = aValue["name"] as? String,
let let photoName = aValue["photo"] as? String,
... {
let meal = Meal(name: name, photo: UIImage(named: photoName)
self.meals.append(meal)
}
And since your Meal.init() seems to return an optional, you could add it also in the if let and avoid the force unwrap of meal.
In this I am getting data from server response after posting parameters and here I need to display it on table view and it should be displayed like shown below in the image 0 is the price for the particular shipping method
already i had written model class for server response data and here it is
struct ShippingMethod {
let carrierCode : String
let priceInclTax : Int
let priceExclTax : Int
let available : Any
let carrierTitle : String
let baseAmount : Int
let methodTitle : String
let amount : Int
let methodCode : String
let errorMessage : Any
init(dict : [String:Any]) {
self.carrierCode = dict["carrier_code"] as! String
self.priceInclTax = dict["price_incl_tax"]! as! Int
self.priceExclTax = dict["price_excl_tax"]! as! Int
self.available = dict["available"]!
self.carrierTitle = dict["carrier_title"] as! String
self.baseAmount = dict["base_amount"]! as! Int
self.methodTitle = dict["method_title"]! as! String
self.amount = dict["amount"]! as! Int
self.methodCode = dict["method_code"] as! String
self.errorMessage = (dict["error_message"] != nil)
}
}
by using this I had formed an array type like this by using code
var finalDict = [String: [String]]()
var responseData = [ShippingMethod]()
do
{
let array = try JSONSerialization.jsonObject(with: data, options: []) as? [[String : Any]]
for item in array! {
self.responseData.append(ShippingMethod.init(dict: item))
}
print(self.responseData)
}
catch let error
{
print("json error:", error)
}
print(self.responseData)
for item in self.responseData {
let dict = item
let carrierTitle = dict.carrierTitle
let methodTitle = dict.methodTitle
if self.finalDict[carrierTitle] == nil {
self.finalDict[carrierTitle] = [String]()
}
self.finalDict[carrierTitle]!.append(methodTitle)
}
print(self.finalDict)
the output of this finalDict is ["Flat Rate": ["Fixed"], "Best Way": ["Table Rate"]] in this carrier title key value pair should be displayed as section title and is Flat Rate and method title key value pair should be displayed as rows in section Fixed but the problem is I need amount key value pair with it also for corresponding method title can anyone help me how to get this ?
Why don't you create another struct for displaying row data:
struct CarrierInfo {
let name:String
let amount:Int
}
Change your finalDict to
var finalDict = [String: [CarrierInfo]]()
and create CarrierInfo instance and set it in finalDict
for item in self.responseData {
let dict = item
let carrierTitle = dict.carrierTitle
let methodTitle = dict.methodTitle
let amount = dict.amount
if self.finalDict[carrierTitle] == nil {
self.finalDict[carrierTitle] = [CarrierInfo]()
}
self.finalDict[carrierTitle]!.append(CarrierInfo(name: carrierTitle, amount: amount))
}
Likewise you can make other required changes. This would neatly wrap your row display data inside a structure.
PS: I have not tested the code in IDE so it may contain typos.
You can assign another dictionary with key as methodTitle and amount as value. i.e., ["fixed":"whatever_amount"]
OR
You can use finalDict differently, like ["Flat Rate": ["tilte":"Fixed","amount":"0"], "Best Way": ["title":"Table Rate","amount":"0"]]
If it is difficult for you to code this, you can revert back.
Edit
You can use the following code to create the array in the second solution I suggested above:
for item in self.responseData {
let dict = item
let carrierTitle = dict.carrierTitle
let methodTitle = dict.methodTitle
let amount = dict.amount
if self.finalDict[carrierTitle] == nil {
self.finalDict[carrierTitle] = [[String:String]]()
}
let innerDict = ["title":methodTitle,"amount":amount]
self.finalDict[carrierTitle]!.append(innerDict)
}
I'm going to display some data from NSArray in the tableViewCell.
Here is my NSArray format
(
{
score = "480.0";
uid = 2;
},
{
score = "550.0";
uid = 1;
}
)
So, how to display for example score?
Here is m code, but it doesn't display it
var gamesRound: NSArray = []
let game = gamesRound[indexPath.row]
//let user = users[Int(game.userId - 1)]
cell.textLabel?.text = game as? String
//cell.detailTextLabel?.text = "\(String(Int(game.score))) PTS"
//print(user.fullname!)
return cell
Change your gamesRound variable to Array of Dictionary like this:
Put some value like this, in viewDidLoad (maybe):
var gamesRound = [[String: Any]]()
To render value on cells of a UITableView
gamesRound = [["score": "480.0", "uid" = 2], ["score": "550.0", "uid": 1]]
Some what like this:
let game = gamesRound[indexPath.row] as! [String: Any]
cell.textLabel?.text = "\(game["score"] as? Int ?? 0)"
cell.detailTextLabel?.text = "\(game["uid"] as? Int ?? 0)"
seems to me that you have an NSDictionary in each position of you NSArray.
So, use this code to get the position that you want:
let game = gamesRound[indexPath.row]
Now the game is an NSDictionary and you only need to extract the information using the key that you want:
let uid = game["uid"]
let score = game["score"]
I hope my example helps you.
Here you have the Array of dictionary so when you write let dict = gamesRound[indexPath.row] you will get the dictionary object and you can get the value by using the key because dictionary has the key value pair while the array has the indexing.
Also, you can Declare array like this
var gamesRound: Array<Dictionary<String,Any>> = []
So you can verify by printing the values step by step:
print(gamesRound)
let dict = gamesRound[indexPath.row] as! Dictionary<String,Any>
print(dict)
let score = dict["score"]
print(dict["score"])
cell.textLabel?.text = "\(score!)"
Try this code,
let gameRound : NSDictionary = yourArray[indexPath.row] as! NSDictionary
let strUid = gameRound["uid"]
cell.textLabel.text = strUid as? String
I want get the below json to my array for showing in UITableview
{
MyPets = (
{
breed = "";
breedvaccinationrecord = "";
"city_registration" = "";
"date_of_birth" = "";
"emergency_contacts" = "";
gender = m;
"pet_id" = 475;
"pet_name" = "IOS PET";
petinfo = "http://name/pet_images/";
"prop_name" = "";
"qr_tag" = 90909090;
species = Canine;
"vaccination_records" = "";
vaccinationrecord = "http://Name/vaccination_records/";
"vet_info" = "";
}
);
}
i am using below code to get values into array
if let dict = response.result.value {
print(response)
let petListArray = dict as! NSDictionary
self.petListArray = petListArray["MyPets"] as! [NSMutableArray]}
in cellForRowAtIndexPath i am using this line to display name in UILabel in TableCell
cell?.petName.text = self.petListArray[indexPath.row].valueForKey("pet_name") as? String
but it is crashing like
fatal error: NSArray element failed to match the Swift Array Element type
i am new to swift 2 please help me thanks in advance
First of all declare petListArray as Swift Array, do not use NSMutable... collection types in Swift at all.
By the way the naming ...ListArray is redundant, I recommend either petList or petArray or simply pets:
var pets = [[String:Any]]()
The root object is a dictionary and the value for key MyPets is an array, so cast
if let result = response.result.value as? [String:Any],
let myPets = result["MyPets"] as? [[String:Any]] {
self.pets = myPets
}
In cellForRow write
let pet = self.pets[indexPath.row]
cell?.petName.text = pet["pet_name"] as? String
It's highly recomenended to use a custom class or struct as model. That avoids a lot of type casting.
let uid = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference().child("users").child((uid)!)
ref.observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
let htest = dictionary["h"] as! String //error is mainly here signal SIGABRT
var inthtest = Int(htest)
if (inthtest==0){
self.checkPointsk()
print("scanning1")
I've tried changing the as String Value To int Value but it still doesn't work
The error is self explanatory. You're trying to cast a number as a string. Replace the below two lines
let htest = dictionary["h"] as! String
var inthtest = Int(htest)
with
var inthtest = dictionary["h"] as! Int
The best way to avoid crashes like this is to use conditional binding.
if var inthtest = dictionary["h"] as? Int{
//Do your stuff
}
else if var inthtest = dictionary["h"] as? String{
if let integerValue = Int(inthtest){
//Do your stuff
}
}