Accessing Nested NSDictionary values in Swift 3.0 - ios

I have the following data I received from Firebase. I have made my snapshotValue a NSDictionary.
self.ref.child("users").child(facebookID_Firebase as! String).observeSingleEvent(of: .value, with: { (snapshot) in
let snapshotValue = snapshot.value as? NSDictionary
print(snapshotValue, "snapshotValue")
//this line of code doesn't work
//self.pictureURL = snapshot["picture"]["data"]["url"]
}) { (error) in
print(error.localizedDescription)
}
I tried How do I manipulate nested dictionaries in Swift, e.g. JSON data? , How to access deeply nested dictionaries in Swift , and other solutions yet no luck.
How do I access the url value inside the data key AND the picture key?
I can make another reference in Firebase and get the value, but I'm trying to save another request. 😓

When you refrence to a key of a Dictionary in swift you get out an unwrapped value. This means it can be nil. You can force unwrap the value or you can use pretty if let =
this should probably work.
if let pictureUrl = snapshot["picture"]["data"]["url"] {
self.pictureURL = pictureUrl
}

Try using :-
if let pictureDict = snapshot.value["picture"] as? [String:AnyObject]{
if let dataDict = pictureDict.value["data"] as? [String:AnyObject]{
self.pictureURL = dataDict.value["url"] as! String
}
}

Inline dictionary unwrapping:
let url = ((snapshot.value as? NSDictionary)?["picture"] as? NSDictionary)?["url"] as? String

You can use the following syntax, that is prettier:
if let pictureDict = snapshot.value["picture"] as? [String:AnyObject],
let dataDict = pictureDict.value["data"] as? [String:AnyObject] {
self.pictureURL = dataDict.value["url"] as! String
}
}

Related

Reading value from nested NSDictionary

Im having trouble accessing a value within an NSDictionary, I'd like to be reading the value for the "user5" key, I can't work out what is going on or how to access this value, Ive attached the screenshot produced by the debugger when i create a breakpoint:
[Here][1]
Thanks for any help you can provide :)
You can try
if let va = values["LMN9xAUOcgsw4c6GJb4"] as? [String:Any] {
if let users = va["users"] as? [String:Any] {
if let user = users["user5"] as? String {
print(user)
}
}
}
let data = NSDictionary()
print((datat.value(forKey: "Key1") as! NSDictionary).value(forKey: "Key2") as! String)

Parse JSONArray contains JSONObjects Swift

hello i'm new to swift and I have responseJson from alamofire consist of jsonArray contain jsonObjects like this
[{"id":"1","name":"person1"},{"id":"2","name":"person2"}]
how i can parse it into array of this custom model
class Person {
var name : String
var id : String
}
i've done a much searching but can't find case identical to mine and i can't use Codable because i'm using xcode 8 and not able to upgrade my xcode version to 9 now
I'm getting the response like this
Alamofire.request(url).responseJSON{ response in
if(response.result.isSuccess)
{
if let jsonarray = response.result.value as? [[String: Any]]
{
//what to do here ?
}
}
}
if let jsonarray = response.result.value as? [[String: Any]]{
//what to do here ?
var persons:[Person] = []
for userDictionary in jsonarray{
guard let id = userDictionary["id"] as? String, let name = userDictionary["name"] as? String else { continue }
persons.append(Person(id, name))
}
//Persons complete.
}
Use guard else for the required variables.
If there are additional variables that could be optional, like var age:Int? in Person, you could do like this:
for userDictionary in jsonarray{
guard let id = userDictionary["id"] as? String, let name = userDictionary["name"] as? String else { continue }
let age = userDictionary["age"] as? Int
persons.append(Person(id, name, age))
}
#Tony,
In swift4 you can codable protocol to parsing the JSON that helps in writing generic code. Suppose if in future requirement came to add dob than its very simple.
And in swift3 you can use object mapper class for same.
If you need more help than please let me know.

Firebase Accessing Snapshot Value Error in Swift 3

I recently upgraded to swift 3 and have been getting an error when trying to access certain things from a snapshot observe event value.
My code:
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let username = snapshot.value!["fullName"] as! String
let homeAddress = snapshot.value!["homeAddress"] as! [Double]
let email = snapshot.value!["email"] as! String
}
The error is around the three variables stated above and states:
Type 'Any' has no subscript members
Any help would be much appreciated
I think that you probably need to cast your snapshot.value as a NSDictionary.
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let username = value?["fullName"] as? String ?? ""
let homeAddress = value?["homeAddress"] as? [Double] ?? []
let email = value?["email"] as? String ?? ""
}
You can take a look on firebase documentation: https://firebase.google.com/docs/database/ios/read-and-write
When Firebase returns data, snapshot.value is of type Any? so as you as the developer can choose to cast it to whatever data type you desire. This means that snapshot.value can be anything from a simple Int to even function types.
Since we know that Firebase Database uses a JSON-tree; pretty much key/value pairing, then you need to cast your snapshot.value to a dictionary as shown below.
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
if let firebaseDic = snapshot.value as? [String: AnyObject] // unwrap it since its an optional
{
let username = firebaseDic["fullName"] as! String
let homeAddress = firebaseDic["homeAddress"] as! [Double]
let email = firebaseDic["email"] as! String
}
else
{
print("Error retrieving FrB data") // snapshot value is nil
}
}

Type 'Any' has no subscript members (firebase)

I am getting this error: "Type 'Any' has no subscript members" when trying to run this block of code:
init(snapshot: FIRDataSnapshot) {
key = snapshot.key
itemRef = snapshot.ref
if let postContent = snapshot.value!["content"] as? String { // error
content = postContent
} else {
content = ""
}
}
I have been searching for an answer and couldn't find one that solved this problem with FireBase. How would I solve this error?
snapshot.value has the type Any?, so you need to cast it to the underlying type before you can subscript it. Since snapshot.value!.dynamicType is NSDictionary, use an optional cast as? NSDictionary to establish the type, and then you can access the value in the dictionary:
if let dict = snapshot.value as? NSDictionary, postContent = dict["content"] as? String {
content = postContent
} else {
content = ""
}
Or, you can do it as a one-liner:
content = (snapshot.value as? NSDictionary)?["content"] as? String ?? ""
I have also a codepiece which allows you to access to the values of the child nodes. I hope this helps you:
if let snapDict = snapShot.value as? [String:AnyObject] {
for child in snapDict{
let shotKey = snapShot.children.nextObject() as! FIRDataSnapshot
if let name = child.value as? [String:AnyObject]{
var _name = name["locationName"]
print(_name)
}
}
}
Best regards,
Nazar Medeiros

Ambiguous use of subscript. Array Swift IOS

I try to compile on device but i get this error. Any help?. In the simulator works perfectly.
I get an ambiguous use of subscript error in the following code and was hoping somebody else has encountered this and know the fix.
case .Success:
if response.response?.statusCode == 200 {
print ("Respuesta 200")
if let value = response.result.value {
let respuestaJSON = JSON(value)
let objsonUSUARIOS = respuestaJSON["d"].object
let arrayUsuarios = objsonUSUARIOS["results"]!
//print ("Usuarios: ",String(arrayUsuarios))
for i in 0 ..< arrayUsuarios!.count{
let boletines = boletinJSON()
if let item = arrayUsuarios![i] as? [String: AnyObject]{
)
if let person = item["Title"] as? String
{
boletines.name = person
}
if let person = item["Portada"] as? String
{
boletines.imagen = person
}
if let person = item["Created"] as? String
{
boletines.fecha = person
}
if let person = item["AttachmentFiles"] as? [String: AnyObject] {
if let itemAttach = person["__deferred"] as? [String: AnyObject]{
if let itemdeferred = itemAttach["uri"] as? String {
boletines.urldescarga = itemdeferred
}
}
}
self.boletin.append(boletines)
self.view.hideToastActivity()
}
}
}
self.tableView.reloadData()
// self.view.hideToastActivity()
}
Inform the compiler what the intermediary object objsonUSUARIOS is of type
let objsonUSUARIOS = respuestaJSON["d"].object
After the above statement, the compiler does not know what kind of object he is dealing with. So make sure that you can actually do all the casting as below
let objsonUSUARIOS = respuestaJSON["d"].object as! Dictionary
let arrayUsuarios = objsonUSUARIOS["results"]! as! Array
The problem is that you have not specified the type of object arrayUsuarios is Array, so try to explicit type cast the arrayUsuarios Array
let arrayUsuarios = objsonUSUARIOS["results"] as! [[String: AnyObject]]

Resources