swift - Failable convenience initializer with optional parameters -
i'm looking best way structure class failable convenience initializer optional parameters. current code:
class member: nsobject { var uid: string let avatarurl: nsurl let created: nsdate let email: string let name: string let provider: string var posts = [post]() var comments = [comment]() // initialize member raw data init(uid: string, avatarurl: nsurl, created: nsdate, email: string, name: string, provider: string){ self.uid = uid self.avatarurl = avatarurl self.created = created self.email = email self.name = name self.provider = provider super.init() } convenience init?(snapshot: fdatasnapshot){ if let uid = snapshot.key { if let avatarurlstring = snapshot.value["avatarurl"] as? string { if let avatarurl = nsurl(string: avatarurlstring) { if let membercreated = snapshot.value["created"] as? nsdate { if let memberemail = snapshot.value["email"] as? string { if let membername = snapshot.value["name"] as? string { if let memberprovider = snapshot.value["provider"] as? string { self.init(uid: uid, avatarurl: avatarurl, created:membercreated, email: memberemail, name: membername, provider: memberprovider) } } } } } } } return nil } }
i need either initialize member manually (init) or passing firebase object (convenience init). if of optionals fail within convenience init, i'd fail.
currently, won't build because:
all stored properties of class instance must initialized before returning nil initializer
not sure i'm missing.
any opinions better way approach welcome.
this known issue in failable initializers swift team still working on improving. say, properties must set before returning nil
, set them (""
or nsdate()
in case). it's bit tedious, necessary.
just clearer, since can little tricky sometimes, here 1 way:
convenience init?(snapshot: fdatasnapshot){ if let uid = snapshot.key { if let avatarurlstring = snapshot.value["avatarurl"] as? string { if let avatarurl = nsurl(string: avatarurlstring) { if let membercreated = snapshot.value["created"] as? nsdate { if let memberemail = snapshot.value["email"] as? string { if let membername = snapshot.value["name"] as? string { if let memberprovider = snapshot.value["provider"] as? string { self.init(uid: uid, avatarurl: avatarurl, created:membercreated, email: memberemail, name: membername, provider: memberprovider) return } } } } } } } self.init(uid: "", avatarurl: nsurl(), created: nsdate(), email: "", name: "", provider: "") return nil }
(in swift 1.2, able stack let's together, make code bit clearer , let use else
rather return
in middle.)
the key in convenience initializer, must call self.init
, if you're going call return nil
later. (the swift team knows annoying, there corner cases difficult deal with.)
Comments
Post a Comment