Currently there is no way to check if a PKCanvasView is blank. I submitted a bug via the feedback app a week ago, but it says "No similar reports." This seems like a pretty big deal, and I was wondering if anyone has been able to check a PKCanvasView to see if it's blank. The demo app uses the PKCanvasViewDelegate to flip a bool when drawing starts, but this is not really valid. If a user draws and then erases back to a blank canvas, it will still report the canvas as "dirty." I don't think saving a bunch of blank canvases is user friendly.
Let's clear up a couple of things this discussion left up in the air.
— PKDrawing is an Obj-C class in Obj-C. For Swift, there is a PencilKit overlay, which causes PKDrawing to be re-defined as a struct with an inner reference to the underlying Obj-C instance. This is a fairly common bridging pattern in Swift, because Swift prefers you to use value semantics over reference semantics when possible. (The "why" to that is a longer discussion.)
If the duplication of the name "PKDrawing" seems confusing, keep in mind that a type name in Swift is qualified by its module name, so the struct's name is really PencilKit.PKDrawing. (Well, you can think of it that way, but the name is actually mangled according to Swift's name rules, so it's something uglier.) The Obj-C class name has no module qualifier. It's just plain "PKDrawing", though the PencilKit overlay forces the compiler to hide that Obj-C class name from you.
— When you use "==" on Obj-C objects in Swift, it actually calls through to the -[isEqual:] method, whose default implementation is pointer equality. IOW, for Obj-C objects in Swift, "==" will default to the equivalent of "===". However, many Obj-C objects have class-specific overrides of -[isEqual:], and in that case, Swift's "==" will typically be different from "===".
That's all just regular Obj-C behavior, expressed in Swift syntax.
— We don't know exactly how the Swift overlay for PKDrawing defines "==", and we don't know how the underlying Obj-C PKDrawing class defines -[isEqual:], so it seems a bit risky to depend on behavior that compares two PKDrawing values for equality. My guess is that Swift "==" just calls through to the underlying Obj-C PKDrawing -[isEqual:], but who knows. Even if you could figure out the current implementation, there's no API contract (AFAIK) that would ensure the same behavior forever more.
After all, is there any reliable intuition about what makes two drawings "equal"?
— There is a .null CGRect as well as a .zero CGRect. The difference is that a .zero CGRect has an origin (0,0), while .null doesn't have an origin. Forming a union of — for example — .zero and (x:1, y: 1, w: 1, h: 1) is the rect (x: 0, y: 0, w: 2, h: 2). By contrast, the union of .null and (x:1, y: 1, w: 1, h: 1) is (x:1, y: 1, w: 1, h: 1) unchanged.
Therefore, I'd expect the correct check for an "empty" drawing would be drawing.bounds.isEmpty, since that would be true for .null as well as any empty rect.
All in all, that's a whole barrel o' Swift fun from what looked like a pretty straightforward question. 🙂