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.
Related
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
How can I filter these json object? I mean I want print only patients whose id is equal to 3.
var patients: Array<AnyObject>? if let obj: AnyObject = manager?.responseObject as AnyObject? {
if let pats = obj["patients"] as! Array<AnyObject>? {
patients = pats
}
}
This is my printed variable
{
patients = (
{
city = "\U0411\U0430\U044f\U043d\U0445\U043e\U043d\U0433\U043e\U0440";
district = "\U0411\U0430\U044f\U043d\U0445\U043e\U043d\U0433\U043e\U0440";
firstname = fdfsdf;
lastname = dsfgsdfg;
"patient_id" = 1064;
"patient_status" = 3;
"register_id" = "\U0430\U043083040411";
}
{
city = "\U0411\U0430\U044f\U043d\U0445\U043e\U043d\U0433\U043e\U0440";
district = "\U0411\U0430\U044f\U043d\U0445\U043e\U043d\U0433\U043e\U0440";
firstname = dwfw;
lastname = dsfsdf;
"patient_id" = 1056;
"patient_status" = 1;
"register_id" = "\U0443\U044399111134";
}
}
Please cast the types down as much as possible.
All types are more specific than AnyObject, JSON dictionaries are always [String:AnyObject] and JSON arrays are Array<[String:AnyObject]>. Use Array<AnyObject> only if the array contains another array or is more nested.
Filter the patients with the filter function.
var patients = Array<[String:AnyObject]>()
if let obj = manager?.responseObject as? [String:AnyObject] {
if let pats = obj["patients"] as? Array<[String:AnyObject]> {
patients = pats.filter { $0["patient_status"] as! Int == 3 }
}
}
Note: In Swift 3 AnyObject has been replaced with Any.
I have a variable content from a NSArray : let content = application["content"]!
When I print content, I have a String :
print(content) -> My content
But when I want to cast my variable to String : let content = application["content"]! as! String
I can't print my variable because it's null :
print(content) -> Could not cast value of type 'NSNull' (0x1a0507768) to 'NSString' (0x1a0511798).
Why ?
UPDATE :
My array when value is not casted :
{
"application_title" = "Marina Kaye";
"application_type" = discussions;
"application_type_name" = Discussions;
content = (
{
content = "Le nouvel album de Marina Kaye";
link = "?message_id=118";
},
{
content = "Son album est num\U00e9ro 1 des";
link = "?message_id=131";
},
{
content = "Le nouvel album s'appel";
link = "?message_id=126";
}
);
"content_title" = "Messages utiles";
"content_type" = "useful_messages";
}
My array when value is casted :
{
"application_title" = "Marina Kaye";
"application_type" = discussions;
"application_type_name" = Discussions;
content = "<null>";
"content_title" = "<null>";
"content_type" = "usefull_messages";
}
I can't cast content to NSArray and content_title to String.
MY CODE :
let applicationsArray = result["applications"]! as! NSArray
for application in applicationsArray {
let applicationTitle = application["application_title"]! as! String
let applicationType = application["application_type"]! as! String
let applicationTypeName = application["application_type_name"]! as! String
let content = application["content"]! as! NSArray
let contentTitle = application["content_title"]! as! String
let contentType = application["content_type"]! as! String
self.listApplications.append(Application(applicationTitle: applicationTitle, applicationType: applicationType, applicationTypeName: applicationTypeName, content: content, contentTitle: contentTitle, contentType: contentType))
}
As you are coding in Swift, you do not need the legacy NSArray and NSDictionary types. Instead, these are now Array and Dictionary, but you do not even have to care about that.
To declare an array, you usually specify the type in square brackets, such as [String]. For a dictionary, you need this for both key and value, separated by a colon, e.g. [String: AnyObject].
From your log output, you have a Dictionary of type [String: AnyObject] with 6 keys; all of them point to String objects, except the "content" one.
The "content" key apparently points to an array of dictionaries. This is written like this: [[String: AnyObject]]. Thus it is not surprising that casting this to String is not successful.
Here is how you can parse the application dictionary's "content":
if let content = application["content"] as? [[String: AnyObject]] {
for item in content {
let text = content["content"] as? String
let link = content["link"] as? String
// do something with this data
}
}
I would recommend defining a class or struct to capture the application object. Your code will be much clearer and easier to maintain.
Why do I get an error when I used valueForKey... I am using same trick like in objectiveC ...
In ObjectiveC, the code is
self.strSubscribe =[responseObject[#"subscribe"] valueForKey:#"subscribe_ids"];
In Swift , the code is
self.strSubscribe = responseObject["subscribe"].valueForKey["subscribe_ids"] as! String
I declare the variables like
var arraySubCategory : NSMutableArray! = NSMutableArray()
var strSubscribe:String!
And I tried to access the value from below response
{
subscribe =
{
"subscribe_ids" = "1,14";
}
}
Edit
It works using Amit and Eric's solution but now for following data
{
data = (
{
"subscribe_ids" = "1,14";
}
);
}
let dictionary = responseObject["data"][0] as! Dictionary<String,AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
OR//
if let dic = responseObject["data"][0] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids
}
but it gives me error:
could not find member 'subscript'
Swift doesn't know the type of responseObject["subscribe"], you have to help the compiler a bit; for example:
if let dic = responseObject["subscribe"] as? [String:String], let ids = dic["subscribe_ids"] {
self.strSubscribe = ids // "1,14"
}
UPDATE:
It's still the same problem: the compiler doesn't know the type of responseObject["data"], so when you try to access the subscript there's an error (because you know it's a dictionary inside the array, but the compiler doesn't).
One solution is to give the type to the compiler by declaring an array of dictionaries in the if let condition:
if let arr = responseObject["data"] as? [[String:String]], let ids = arr[0]["subscribe_ids"] {
self.strSubscribe = ids
}
Notice that it's [[String:String]] (array of dictionaries), not [String:String] (dictionary).
Write like this.
let dictionary = responseObject["subscribe"] as! Dictionary<String, AnyObject>
self.strSubscribe = dictionary["subscribe_ids"] as! String
Since responseObject["subscribe"] will give a AnyObject? output and AnyObject does not have any member called valueForKey.