I was using Dictionary now we have to use [String:Any]
func getCompanyNameFromFireBase(uid:String, passWord: String) {
if CompanyData.companyName == "" {
WhoAreYouRefKey.observe(.value){ (snap7: FIRDataSnapshot) in
let CompanyLoaderFromFireBaseDictionary:[String : Any] = ((snap7.value!) as! NSDictionary) as! [String : Any]
for this in CompanyLoaderFromFireBaseDictionary.allKeys {
WhoAreYouRefKey.child("\(this as! String)").observe(.Value){ (snap2: FIRDataSnapshot) in
let array = (snap2.value) as! Dictionary
It fails because it is not seeing the keys or values.
func getCompanyNameFromFireBase(uid:String, passWord: String) {
if CompanyData.companyName == "" {
WhoAreYouRefKey.observe(.value){ (snap7: FIRDataSnapshot) in
let temp[String : Any] = ((snap7.value!) as! [String : Any]
let CompanyLoaderFromFireBaseDictionary = temp as! NSDictionary
for this in CompanyLoaderFromFireBaseDictionary.allKeys {
WhoAreYouRefKey.child("\(this as! String)").observe(.Value){ (snap2: FIRDataSnapshot) in
let array = (snap2.value) as! Dictionary
Related
I'm trying to convert an objective c function to swift which is.
+(NSString *)extractNameWithDictionary:(NSDictionary *)dictionary
{
NSDictionary *assets = dictionary[#"assets"];
NSDictionary *item = dictionary[#"item"];
NSArray *facilityAssets = item[#"assets"];
NSDictionary *facilities = facilityAssets[0];
NSDictionary *asset = assets[facilities[#"content"]];
return asset[scs_name] ? : #"";
}
To
func extractNameWithDictionary(dictionary: [AnyHashable : Any]) -> String {
guard let assets = dictionary["assets"] as? [AnyHashable : Any],
let item = dictionary["item"] as? [AnyHashable : Any],
let facilityAssets = item["assets"] as? [Any],
let facilities = facilityAssets[0] as? [AnyHashable : Any],
let asset = assets[facilities["content"]] else { return "" }
return asset[scs_name] ?? ""
}
but in the last constant: let asset = assets[facilities["content"]] I'm getting:
Cannot subscript a value of type '[AnyHashable : Any]' with an index of type 'Any?'
Any help with this?
You can try
func extractNameWithDictionary(dictionary: [String : Any]) -> String {
guard let assets = dictionary["assets"] as? [String : Any],
let item = dictionary["item"] as? [String : Any],
let facilityAssets = item["assets"] as? [Any],
let facilities = facilityAssets[0] as? [String : Any],
let asset = assets[facilities["content"] as? String ?? "" ] as? [String:Any] else { return "" }
return asset[scs_name] as? String ?? ""
}
This
facilities["content"]
returns Any that you can't use in dictionary named assets as it's key is of type AnyHashable
The simplest approach is to just continue your system of unloading to include the content step:
...
let facilities = facilityAssets[0] as? [AnyHashable : Any],
let content = facilities["content"] as? String,
let asset = assets[content] as? [AnyHashable: String]
else { return "" }
You might move on from there to tighten up you types a bit:
func extractNameWithDictionary(dictionary: [String : Any]) -> String {
guard let assets = dictionary["assets"] as? [String : Any],
let item = dictionary["item"] as? [String : Any],
let facilityAssets = item["assets"] as? [[String : Any]],
let content = facilityAssets.first?["content"] as? String,
let asset = assets[content] as? [String: String],
let name = asset[scs_name]
else { return "" }
return name
}
As you work more on this project, however, you'll want to get rid of that NSDictionary entirely, and replace it with a proper struct/class that has typed properties rather than having to do all of this as? madness. That's only showing up because of the use of a dictionary rather than a struct or class.
I’m trying to create a TableView with elements that comes from a REST Service, It’s a list of coupons that has description, title, category and images. So I deserialize the data first, put it in an array and then convert it into an specific array per each section, but my loop is not working, can anyone help me please?
This is my code:
var couponsTitle : [String] = []
var couponsDesc : [String] = []
var couponsCat : [String] = []
func getCoupons(){
let miURL = URL(string: RequestConstants.requestUrlBase)
let request = NSMutableURLRequest(url: miURL!)
request.httpMethod = "GET"
if let data = try? Data(contentsOf: miURL! as URL) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
let parseJSON = json
let object = parseJSON?["object"] as! NSDictionary
let mainCoupon = object["mainCoupon"] as! NSArray
let coupons = object["coupons"] as! NSArray
for i in mainCoupon {
self.couponsCat.append((mainCoupon[i as! Int] as AnyObject).value(forKey: "category"))
}
for i in coupons {
self.couponsCat.append((coupons[i as! Int] as AnyObject).value(forKey: "category"))
}
for i in mainCoupon {
self.couponsDesc.append((mainCoupon[i as! Int] as AnyObject).value(forKey: “description"))
}
for i in coupons {
self.couponsDesc.append((coupons[i as! Int] as AnyObject).value(forKey: “description"))
}
for i in mainCoupon {
self.couponsTitle.append((mainCoupon[i as! Int] as AnyObject).value(forKey: “name"))
}
for i in coupons {
self.couponsTitle.append((coupons[i as! Int] as AnyObject).value(forKey: “name"))
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell
cell.couponTitle.text = couponsTitle[indexPath.row]
cell.couponDescription.text = couponsDesc[indexPath.row].
cell.couponCategory.text = couponsCat[indexPath.row]
return cell
}
My biggest issue is that I don’t know how to put in a loop the array but with the specification of each section (I mean, the title, description, category, etc.) Any idea?
Rather than having three arrays (one for each property), why not have a custom class for Coupon that has three properties?
class Coupon: AnyObject {
var description: String
var title: String
var category: String
init(description: String, title: String, category: String) {
self.description = description
self.title = title
self.category = category
}
}
If you do it that way, you can avoid so many loops by doing something like this
for coupon in mainCoupon {
let description = mainCoupon["description"]
let title = mainCoupon["name"]
let category = mainCoupon["category"]
let newCoupon = Coupon(description: description, title: title, category: category)
couponsArray.append(newCoupon)
}
Data:
tried get data from JSON
has code with Swift run on Playground
var roadWayStatusArray = [AnyObject]()
let url = URL(string: "http://od.moi.gov.tw/data/api/pbs")
let data = try? Data(contentsOf: url!)
let json = try? JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
if let results = json as? [String : AnyObject] {
if let result = results["result"] as? [[String : AnyObject]] {
for data in result {
let happendate = data["happendate"] as? String
roadWayStatusArray.append(data as AnyObject!)
}
}
}
I has tried using roadWayStatusArray.sort(by: >) but Xcode report me Ambiguous reference member '>'
How to create sort by hapendate or happentime
Your roadWayStatusArray is an array of AnyObject. There is no > operator defined for AnyObject.
The objects in roadWayStatusArray are actually dictionaries that look like this:
{
UID = "10602090007-0";
areaNm = "\U4e2d\U5c71\U9ad8\U901f\U516c\U8def-\U570b\U9053\Uff11\U865f";
comment = "\U5317\U4e0a.\U4e2d\U58e2\U670d\U52d9\U5340 \U51fa\U53e3\U531d\U9053\U4e2d \U53f3\U5074 \U5c0f\U5ba2\U8eca\U505c\U653e\Uff0c\U99d5\U99db\U7591\U4f3c\U7761\U8457\U4e86";
direction = "\U5317\U4e0a";
happendate = "2017-02-09";
happentime = "01:08:00.0000000";
modDttm = "2017-02-09 01:15:43.603";
region = N;
road = "";
roadtype = "\U5176\U4ed6";
srcdetail = "\U71b1\U5fc3\U807d\U773e";
x1 = "121.73558";
y1 = "25.12263";
}
You need to call sort(by:) with a closure that determines the sort order. For example, if you want to sort by happendate and then happentime:
roadWayStatusArray.sort(by: { (lhsAny, rhsAny) -> Bool in
let lhs = lhsAny as? [String: AnyObject]
let rhs = lhsAny as? [String: AnyObject]
let lhsKey = (lhs?["happendate"] as? String ?? "", lhs?["happentime"] as? String ?? "")
let rhsKey = (rhs?["happendate"] as? String ?? "", rhs?["happentime"] as? String ?? "")
return lhsKey < rhsKey
})
I want to get long_name from this JSON file I can just access 'results' with this code:
let url = URL(string: "https://maps.googleapis.com/maps/api/geocode/json?latlng=35.7229513,51.3566039&language=fa&key=AIzaSyBXOPT1jEYizWZHOKLwv4dhacgYTcmn3I4")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
}
else{
if let urlcontent = data {
do{
let jsonResult = try JSONSerialization.jsonObject(with: urlcontent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
print(jsonResult["results"]!)
if let jsonResult = jsonResult["results"] as? [String: Any] {
if let address_components = jsonResult["address_components"] as? [String: Any] {
print(address_components)
if let long_name = address_components["long_name"] as? [String: Any] {
print(long_name)
}
}
}
}
catch{
print("json failed")
}
}
}
}
task.resume()
But I'm just getting result this is my JSON file:
https://maps.googleapis.com/maps/api/geocode/json?latlng=35.7339859%2C51.3393980&sensor=true_or_false&language=fa
Your result key contains Array as value not Dictionary so simply change [String:Any] to [[String:Any]] and then access address_components from the each dictionary objects of resultsArray, now address_components is also array of dictionary and long_name is inside that dictionary. So try like this.
if let resultsArray = jsonResult["results"] as? [[String: Any]] {
for dic in resultsArray {
if let addressArray = dic["address_components"] as? [[String:Any]] {
for address in addressArray {
if let longName = address["long_name"] as? String {
print(longName)
}
}
}
}
}
from this link I would like to get the commonName
I tried this but it didn't work?!
let commonName = object["toLocationDisambiguation"][0]["disambiguationOptions"][1]["place"][2]["commonName"].stringValue
Option 1 (Normal)
if let toLocationDisambiguation = object["toLocationDisambiguation"] as? Dictionary<String, AnyObject> {
if let disambiguationOptions = toLocationDisambiguation["disambiguationOptions"] as? Array<AnyObject> {
if let first = disambiguationOptions.first as? [String: AnyObject] {
if let place = first["place"] as? [String: AnyObject] {
let commonName = place["commonName"] as! String
print("Common Name: ", commonName)
}
}
}
}
Option 2 (Type Aliases)
typealias MyDictionary = [String: AnyObject]
typealias MyArray = [MyDictionary]
if let toLocationDisambiguation = object["toLocationDisambiguation"] as? MyDictionary {
if let disambiguationOptions = toLocationDisambiguation["disambiguationOptions"] as? MyArray {
if let first = disambiguationOptions.first {
if let place = first["place"] as? MyDictionary {
let commonName = place["commonName"] as! String
print("Common Name: ", commonName)
}
}
}
}
Option 3 (SwiftyJSON for Objective-C like syntax)
Take a look at SwiftyJSON.
let object = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject>
let json = JSON(object)
let commonName = json["toLocationDisambiguation"]["disambiguationOptions"][0]["place"]["commonName"].stringValue
print("Common Name: ", commonName)