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)
Related
public func getAllItems(completion: #escaping (Result<[Item], Error>) -> Void)
{
database.child("Items").observe(.value, with: {snapshot in
guard (snapshot.value as? [[String: Any]]) == nil else{
completion(.failure(DatabaseError.failedToFetch))
return
}
var newUrlArray: [Item] = []
var newItemArray: [Item] = []
for child in snapshot.children{
if let childSnapshots = child as? DataSnapshot,
let dict = childSnapshots.value as? [String:Any],
let title = dict["title"] as? String,
let content = dict["content"] as? String,
let itemId = dict["itemid"] as? String,
let price = dict["price"] as? Int{
let item = Item(title: title, content: content, itemId: itemId, price: price, urs: newUrlArray)
newItemArray.append(item)
}
}
completion(.success(newDataArray))
})
}
My question is how can I get urls that shown in picture as an array or is it possible.
You need to go one level deeper into your JSON/Snapshot hierarchy to get the URLs.
If I remove the non-URL code for a moment for readability, it'd be something like:
for child in snapshot.children{
if let childSnapshots = child as? DataSnapshot,
let dict = childSnapshots.value as? [String:Any],
let urls = childSnapshots.childSnapshot(atPath: "urls").value as? [String:Any],
...
}
}
So urls above is another dictionary, where you can loop over its keys to get the URL values.
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.
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)
}
}
}
}
}
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