How to use values globally parsed from JSONResponse. So, far able to extract the array from JSONResponse, but after that trying to put that array in an global array, not getting how to declare global array. somehow managed to do that but now not able to extract values index wise from that array. Please guide.
Code tried now:
if (JSONResponse["status"].intValue == 1)
{
if let fetchedImages = JSONResponse["data"].arrayObject {
self.arrResponseReceived = fetchedImages
}
print("self.arrResponseReceived", self.arrResponseReceived)
}
else
{
CommonMethodsClass.showAlertMessage(vc: self, titleStr: "Error!", messageStr: strMsg)
}
Code tried earlier:
arrResponseReceived = JSONResponse["data"].arrayValue
Global variable declared for array is:
var arrResponseReceived : [Any] = []
Data to parse is:
{
data = (
{
AverageRating = 4;
Image = "<null>";
IsActive = 1;
Latitude = "28.567806";
Longitude = "77.3236273";
SalonAddress = " Sec-58, India";
SalonEmail = "vy.chan#th-rce.com";
SalonID = 1;
SalonImage = "";
SalonMobile = 9999888877;
SalonName = Affinity;
SalonPhone = 9999888877;
TimeIntervalminutes = 20;
},
{
AverageRating = 5;
Image = "<null>";
IsActive = 1;
Latitude = "";
Longitude = "";
SalonAddress = "Mall, India";
SalonEmail = "rad#th-rce.com";
SalonID = 3;
SalonImage = "";
SalonMobile = 9999888877;
SalonName = Looks;
SalonPhone = 9999888877;
TimeIntervalminutes = 30;
}
);
message = "";
status = 1;
}
You should definite the Class of what is inside of JSONResponse["data"].arrayValue, or how Xcode knows it.
If you want to get an data array which is made of Dictionary , here is how I cheated it out.
func getDatas(from json: Any?) -> [Dictionary] {
guard let json = json as? NSDictionary, let entries = json.value(forKeyPath: "data") as? [NSDictionary] else {
return []
}
return entries.flatMap { entry in
guard let dictionary = entry as? NSDictionary else {
return nil
}
return dictionary
}
}
you call it as such
self.arrResponseReceived = getDatas(from: json)
NSDictionary has the method value(forKeyPath:) that is near magic. Calling json.value(forKeyPath: "data") returns an array of dictionaries. Each dictionary is an "entry" object in the json. Next, I map each entry which returns a dictionary.
If this is something more than a quick solution, then I would consider adding SwiftyJSON to your project.
func getDatas(from json: Any?) -> [Dicitonary] {
return JSON(json)["data"].arrayValue.flatMap { entry in
guard let dictionary = entry as? NSDictionary else {
return nil
}
return dictionary
}
}
Related
I have a dictionary that looks like this, I want to remove *all elements that contain stock = 0.
variations = {
"64FB5468-96E9-41A4-A779-3FB57FF1296B" = {
price = 10;
sku = 123456;
stock = 1;
volume = 1L;
};
"A5EDB714-3D39-42DA-9A5C-2392D39C3AEB" = {
price = 20;
sku = 254648;
stock = 0;
volume = 2L;
};
"BCA98B51-B058-4ABE-9010-54B080B819FB" = {
price = 30;
sku = 284964;
stock = 0;
volume = 3L;
};
};
I used the code below, however, it returns found nil while unwrapping error. How to properly remove the dictionary that has 0 stock inside variations dictionary? kSTOCK is a constant for string "stock"
let filterAllItems = self.allItems.filter({(($0.variations as AnyObject)[$0] as! [String:Any])[kSTOCK] as! Int > 0})
Assuming allItems is a [String:Any] dictionary make a (mutable) copy of variations, filter the objects, remove the values of the found keys and reassign the dictionary to allItems
if var variations = allItems["variations"] as? [String:[String:Any]] {
let allItemsWithStock0 = variations.filter({($0.value["stock"] as? Int) == 0})
for (key, _) in allItemsWithStock0 {
variations.removeValue(forKey: key)
}
allItems["variations"] = variations
}
public extension Dictionary {
#inlinable public mutating func removeIf(condition: (Self.Element) -> Bool) {
for (key, _) in filter(condition) { removeValue(forKey: key) }
}
}
I am trying to append to an NSMutableDictionary with the following code:
let RSVPDirectory = NSMutableDictionary()
for i in 0..<self.RSVPs.count {
var tmp = self.RSVPs[i]
var firstLetter = String()
if(tmp["lastname"] is NSNull)
{
firstLetter = ((tmp["email"] as? NSString)?.substring(to: 1).uppercased())!
}
else
{
firstLetter = ((tmp["lastname"] as? NSString)?.substring(to: 1).uppercased())!
}
if RSVPDirectory[firstLetter] == nil {
RSVPDirectory[firstLetter] = [AnyHashable]()
}
RSVPDirectory[firstLetter] = tmp
}
My problem with this is that I am expecting multiple tmp inside RSVPDirectory[firstLetter] but it only adds the first one as if its overriding the previous tmp
How do I append to NSMutableDictionary in swift, I know in objective-c you can do this:
[[RSVPDirectory objectForKey:firstLetter] addObject:tmp];
What would be the equivalent to that in swift?
Try the below code in a playground you will see the output, hope this gives you an idea.
func upperCaseFirstLetter(_ str: String) -> String {
guard let first = str.first else { return "" }
return "\(first)".uppercased()
}
var RSVPs = [[String:String]]()
var RSVPDirectory = [String: [[String:String]]]()
//Test Data
var str = ["email":"test1#c.com"]
RSVPs.append(str)
str = ["lastname":"Atest2"]
RSVPs.append(str)
for i in 0..<RSVPs.count {
var tmp = RSVPs[i]
var firstLetter = ""
if(tmp["lastname"] == nil) {
firstLetter = upperCaseFirstLetter(tmp["email"]!)
} else {
firstLetter = upperCaseFirstLetter(tmp["lastname"]!)
}
if RSVPDirectory[firstLetter] == nil {
RSVPDirectory[firstLetter] = [[String:String]]()
}
RSVPDirectory[firstLetter]?.append(tmp)
}
print(RSVPDirectory)
This is the native Swift version of your Objective-C-ish code.
It uses the Dictionary(grouping API of Swift 4
let RSVPDirectory = Dictionary(grouping: RSVPs) { (dictionary) -> String in
if let lastName = dictionary["lastname"] as? String {
return String(lastName.prefix(1).uppercased())
} else if let email = dictionary["email"] as? String {
return String(email.prefix(1).uppercased())
} else {
return "🚫"
}
}
Yes you are actually replacing the RSVPDirectory[firstLetter], overriding it every time with new tmp.
What you are looking for is this:
//RSVPDirectory[firstLetter] = tmp //Replace this line with below code
let tempArray = RSVPDirectory[firstLetter] as? [AnyHashable]
tempArray?.append(tmp)
RSVPDirectory[firstLetter] = tmpArray
Here I have used a tempArray because we want to mutate the array. Accessing it directly and trying to append new value will in-turn try to mutate an immutable value. So first I have got the array in the tempArray and then after mutating the array I swapped it back in the dictionary with updated values.
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.
I've been trying to find out how to save a part of a JSON response from Alamofire as a variable to make an if statement and can't seem to find how to do it.
I made a piece of code to use as an example for the question which consists of the following:
import UIKit
import Alamofire
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Alamofire.request("http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=44143256ee15e9c3f521ca062463dd8d").responseJSON { response in
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
}
}
I get the following response from the API request:
JSON: {
base = stations;
clouds = {
all = 0;
};
cod = 200;
coord = {
lat = "51.51";
lon = "-0.13";
};
dt = 1485031800;
id = 2643743;
main = {
humidity = 83;
pressure = 1026;
temp = "270.54";
"temp_max" = "273.15";
"temp_min" = "267.15";
};
name = London;
sys = {
country = GB;
id = 5091;
message = "0.0038";
sunrise = 1484985141;
sunset = 1485016345;
type = 1;
};
visibility = 7000;
weather = (
{
description = haze;
icon = 50n;
id = 721;
main = Haze;
}
);
wind = {
speed = 1;
};
}
From this JSON response I would like to save the weather description so I could use the following statement:
if var currentWeather = sunny {
return "Nice day!"
} else {
return "Uh-Oh, keep warm!"
}
If anyone could help me with this I would greatly appreciate it! If I have to use SwiftyJSON to make it easier that's fine I've just been struggling with this for a while and need to figure it out!
You can parse your result following the printout of your JSON response:
guard let JSON = response.result.value as? [String:Any],
let weather = JSON["weather"] as? [[String:Any]] else {
print("Could not parse weather values")
return
}
for element in weather {
if let description = element["description"] as? String {
print(description)
}
}
If you wanted to save the result, or do something based on a certain result as you described, you could insert something else instead of just print(description) like:
if description == "sunny" {
//do something
}
Let me know if this makes sense. Keep in mind that ( and ) in the Xcode console means "Array".
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.