Understanding Swift's Closure Type Requirements -
i'm trying habit of doing things swifty way instead of translating obj-c.
i'm doing project parse, , after fetching bunch of parse objects, want first sort them, extract particular property them. i'm trying right now:
if let notifications = fetchedobjects as? [pfobject] { // line tells me "cannot invoke 'sorted' argument list of type '((_, _) -> _)' let sortedmessages: [string] = notifications.sorted { $0.createdat.compare($1.createdat) == .orderedascending } }
pfobject
has createdat
property declared this: var createdat: nsdate? { }
.
what missing here messes swift's type checking?
here's want after figuring out above error:
if let notifications = fetchedobjects as? [pfobject] { let sortedmessages: [string] = notifications.sorted({ $0.createdat.compare($1.createdat) == .orderedascending }).map { $0["message"] } }
this looks me types should clear , matching.
update
i came today , got working. didn't write in original post, yesterday did try force unwrap createdat
optional too:
if let notifications = fetchedobjects as? [pfobject] { // line tells me "cannot invoke 'sorted' argument list of type '((_, _) -> _)' let sortedmessages: [string] = notifications.sorted { $0.createdat!.compare($1.createdat!) == .orderedascending } }
that giving me exact same error. 1 thing i've learned playing swift far when it's giving cryptic type mismatch errors, it's best explicitly add type declarations every variable - leads more specific error messages. so, today, wrote above code this:
if let notifications = objects as? [pfobject] { let sortedmessages: [string] = notifications.sorted { (lhs: pfobject, rhs: pfobject) -> bool in return rhs.createdat!.compare(lhs.createdat!) == .orderedascending }.map { $0["message"] as! string } }
this seems compile without problem. if rely on type inference:
if let notifications = objects as? [pfobject] { let sortedmessages: [string] = notifications.sorted { lhs, rhs in return rhs.createdat!.compare(lhs.createdat!) == .orderedascending }.map { $0["message"] as! string } }
i error on map
: cannot invoke 'map' argument list of type '((_) -> _)'
.
it looks me this:
if let notifications = objects as? [pfobject] { let sortedmessages: [string] = notifications.sorted { $0.createdat!.compare($1.createdat!) == .orderedascending } .map { $0["message"] as! string } }
should valid, swift's type inference isn't snuff yet... (?). i'm not comfortable letting myself off hook , blame language, looks reasonable in case. missing something?
the types don't quite match up. createdat
optional
, , compare
method takes in non-optional. also, without knowing subscripting pfobject
returns, if it's dictionary, guess it's anyobject!
or anyobject?
, in case need type-cast , possibly force-unwrapped !
. following code compile:
notifications.sorted { switch ($0.createdat, $1.createdat) { case (.some(let first), .some(let second)): return first.compare(second) == .orderedascending default: return true } }.map { $0["message"]! string }
note in swift 1.2, you'll need use as!
instead of as
since unsafe cast (from anyobject
string
). if there's chance of message
being nil on object, may want have sort of fallback:
.map { $0["message"] as? string ?? "default message" }
Comments
Post a Comment