1

I'm using socket.io Swift Library. With the following line of code,

socket.on("info") { (dataArray, socketAck) -> Void in
            let user = dataArray[0] as? User
            print(user._id)
}

dataArray[0] is a valid object but user appears to be nil after casting.

Since dataArray[0] returns as an AnyObject, how can i cast AnyObject to User Object?. Or somehow manage to do what i want with a different approach?

Socket Class

User Class

Serhan Oztekin
  • 475
  • 7
  • 20
  • 1
    An optional downcast using `as?` will return `nil` if the cast fails. What is `dataArray[0].dynamicType`? Are you sure it's a `User`? – JAL Jul 14 '16 at 13:29
  • hey @JAL, dataArray is [AnyObject], dataArray[0] is AnyObject when i look at the debugger but this line print(dataArray[0].dynamicType) prints out "__NSDictionaryM" i am confused – Serhan Oztekin Jul 14 '16 at 13:35
  • Looks like `dataArray` is actually an array of dictionaries and not `User` objects like you think. Try casting `dataArray[0]` as `[String : AnyObject]` and printing the keys and values. – JAL Jul 14 '16 at 13:37
  • let test = dataArray[0] as [String : AnyObject]; when i do print(test.values), prints out "LazyMapCollection, AnyObject>(_base: " which i do not really understand @JAL – Serhan Oztekin Jul 14 '16 at 13:46
  • Are you sure this code does compile? Because `user` should be an optional and you are accessing its `_id` property without optional chaining or unwrapping. – Luca Angeletti Jul 14 '16 at 13:57
  • yes it compiles, but user returns nil instead of giving errors @appzYourLife – Serhan Oztekin Jul 14 '16 at 13:58
  • I am pretty sure this code cannot compile. There is a compile error here `print(user._id)`. This is the error `error: value of optional type 'User?' not unwrapped; did you mean to use '!' or '?'?` – Luca Angeletti Jul 14 '16 at 13:59
  • i get no compile errors, but if so, do you have any ideas on the solution? @appzYourLife – Serhan Oztekin Jul 14 '16 at 14:02
  • @SerhanOztekin: Could you please paste a screenshot of your Xcode where I can see that snipped of code? – Luca Angeletti Jul 14 '16 at 14:06
  • Sure thing, but which part do you want? cause the screenshot of the part i'm having trouble with will be the same as the above code. @appzYourLife – Serhan Oztekin Jul 14 '16 at 14:10
  • @SerhanOztekin: The screenshot of exactly the snippet you added to your question. I would also need to see the code for the `User` class. Thank you. – Luca Angeletti Jul 14 '16 at 14:12
  • Screenshots added, thanks @appzYourLife – Serhan Oztekin Jul 14 '16 at 14:18
  • @SerhanOztekin: Oohh! As I suspected it is `user!._id` and not `user._id` ;-) – Luca Angeletti Jul 14 '16 at 14:23

3 Answers3

3

Since after this line

let user = dataArray[0] as? User

you have a nil value inside user it means that you don't have a User value at the first position of dataArray.

Since dataArray comes from a server (as I guess) it probably contains a serialized version of User.

Now we really need to know what really dataArray[0] is. However...

if dataArray[0] contains NSData

In this case try this

let json = JSON(dataArray[0] as! NSData)
let user = User(json:json)
Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
0

You need to create a constructor that accept AnyObject and read data in it. I guess in this case dataArray[0] is an JSON Object.

class User {
  init(data: [String: AnyObject]) {
     username = data["username"] as? String ?? ""
  }
}
Daniel Tran
  • 6,083
  • 12
  • 25
0

This is how i manage mine:

// Structure used as parameter
struct InfoStruct {
var nome: String = ""
var sobrenome:String = ""
var nascimentoTimestamp: NSNumber = 0

init() {

}

// Struct to AnyObject
func toAnyObject() -> Any {
    var dic = [String:AnyObject?]()

    if (nome != "") { dic["nome"] = nome as AnyObject }
    if (sobrenome != "") { dic["sobrenome"] = sobrenome as AnyObject }
    if (nascimentoTimestamp != 0) { dic["nascimentoTimestamp"] = nascimentoTimestamp as AnyObject }

    return dic
}

// AnyObject to Struct
func fromAnyObject(dic:[String:AnyObject]) -> InfoStruct {
    var retorno = InfoStruct()

    if (dic["nome"] != nil) { retorno.nome = dic["nome"] as? String ?? "" }
    if (dic["sobrenome"] != nil) { retorno.sobrenome = dic["sobrenome"] as? String ?? "" }
    if (dic["nascimentoTimestamp"] != nil) { retorno.nascimentoTimestamp = dic["nascimentoTimestamp"] as? NSNumber ?? 0 }

    return retorno
} }


// User class
class Usuario: NSObject {
var key: String
var admin: Bool
var info: InfoStruct // Struct parameter

init(_ key: String?) {
    self.key = key ?? ""
    admin = false
    info = InfoStruct() // Initializing struct
}

// From Class to AnyObject
func toAnyObject() -> Any {
    var dic = [String:AnyObject?]()

    if (key != "") { dic["key"] = key as AnyObject }
    if (admin != false) { dic["admin"] = admin as AnyObject }
    dic["info"] = info.toAnyObject() as AnyObject // Struct

    return dic
}

// From AnyObject to Class
func fromAnyObject(dic:[String:AnyObject]) -> Usuario {
    let retorno = Usuario(dic["key"] as? String)

    if (dic["key"] != nil) { retorno.key = dic["key"] as? String ?? "" }
    if (dic["admin"] != nil) { retorno.admin = dic["admin"] as? Bool ?? false }
    if (dic["info"] != nil) { retorno.info = InfoStruct.init().fromAnyObject(dic: dic["info"] as! [String : AnyObject]) } // Struct

    return retorno
} }

// Using
let dao = FirebaseDAO.init(_type: FirebaseDAOType.firebaseDAOTypeUser)
dao.loadValue(key: uid) { (error, values:[String : AnyObject]) in
     if error == nil {
          let user = Usuario(values["key"] as? String).fromAnyObject(dic: values)
     }
}

I hope it helps!

Anderson Bressane
  • 378
  • 1
  • 5
  • 15