swiftstructnslog

Can I use NSLog with Swift structs?


I would like to be able to use NSLog with Swift structs. Can I? What I'm doing right now is:

extension CGRect {
    var description:String {
        return "\(self.left),\(self.top)_|\(self.width),\(self.height)"
    }
 }

NSLog("rect for something %@", self.someView.frame.description)

I had hoped that simply adding the description var to CGRect would be enough and I wouldn't need to explicitly add the .description in the NSLog() call. But when I try that I get

Argument type 'CGRect' does not conform to expected type 'CVarArgType'

It seems that arrays of structs have similar issues (because arrays are structs too?)


Solution

  • As far as NSLog is concerned, CGRect is not a Swift struct. It's a C struct. And there is already a C function that lets you log one: NSStringFromCGRect. That is exactly what this function is for:

    NSLog("rect for something %@", NSStringFromCGRect(self.someView.frame))
    

    On the other hand, Swift does already give a CGRect its own string representation, and you can get it simply by asking for that String:

    NSLog("rect for something %@", String(describing: self.someView.frame))
    

    But you cannot use a CGRect directly in any kind of NSLog call. It isn't something that has a corresponding format specifier. If you want to use a CGRect with NSLog, you must pass it through some call that yields something NSLog can deal with. The fact that you are writing this code in Swift is irrelevant; to use NSLog, you must use it exactly as if this were Objective-C/C, because NSLog is Objective-C/C.

    What isn't quite clear is why you're using NSLog here at all, since it doesn't sound like you have much idea what you're doing. And besides, print will do this for you and it will automatically call your description if you conform to Printable (now called CustomStringConvertible because Apple doesn't care how long and ugly the names of things are).