NikolaM NikolaM - 2 months ago 25
Swift Question

Swift, Firebase: `setValue` giving error "AnyObject cannot be used with Dictionary Literal"

I am experiencing an error

Contextual type AnyObject cannot be used within dictionary literal
in that func
addPet
down there, while trying to populate database with the
newPet
argument constituents in a dictionary.

import Foundation
import Firebase

struct Pet {
var name:String?
var type:String?
var age:Int?
var feedingList:[String]
var walkingList:[String]
}

struct User {
var currentId:String?
var numberOfPets:Int?
var pets:[Pet]

}

class petBrain {

var reff = FIRDatabaseReference()
var currentUser:User = User(currentId: "",numberOfPets: 0,pets: [])

init(){
self.reff = FIRDatabase.database().reference()
}

func setUserId(cId:String?){
self.currentUser.currentId = cId
}

func addPet(newPet:Pet) {
self.reff.child("pets").childByAutoId().setValue(["name":newPet.name, "type":newPet.type, "age":newPet.age, "fList":newPet.feedingList, "wList":newPet.walkingList])
}


}


I have already done this in other viewController, similarly for users and its working fine in dictionary shape (producing no error)

let em = emailTextField.text!
let us = usernameTextField.text!

...

else {
print("User created! Loging in.")
self.login()
// adding user to DB of users
self.ref.child("users").child(user!.uid).setValue(["email":em, "username":us])
}


What did i do wrong in the pets case? its maybe due to struct, or struct element types? Are those two structs well defined?

Answer
  • ? is used if the value can become nil in the future.
  • ! is used if it really shouldn't become nil in the future, but it needs to be nil initially.

See the problem is Swift is a strictly typed language, if you declare a variable ? you are saying that it's of type nil. So a dictionary cant tell what type of a value would it be storing....

var myVar : String? // Look myVar, you and your type is completely nil as of now

var myVar : String! // Look myVar, your value is nil as of now but your type is certainly of String

Just change your code to this:-

     struct Pet {
         var name:String!
         var type:String!
         var age:Int!
         var feedingList:[String]
         var walkingList:[String]
     }

     struct User {
         var currentId:String?
         var numberOfPets:Int?
         var pets:[Pet]

     }

     class petBrain {

         var reff = FIRDatabaseReference()
         var currentUser:User = User(currentId: "",numberOfPets: 0,pets: [])

         init(){
             self.reff = FIRDatabase.database().reference()
         }

         func setUserId(cId:String?){
             self.currentUser.currentId = cId
         }

         func addPet(newPet:Pet) {

             let dict = ["name":newPet.name, "type":newPet.type, "age":newPet.age, "fList":newPet.feedingList, "wList":newPet.walkingList]

             self.reff.child("pets").childByAutoId().setValue(dict)
         }


     }