• Startup time is noticeably slower than native apps. Importing Cocoa makes Python parse a ton of code.
• Cocoa just doesn't fit Python's naming conventions. You get long method names with underscores where arguments should be, followed by many unlabelled arguments. The worst thing is that 1-arg methods, which otherwise look like normal Python methods, have to have an underscore suffix (`foo_`).
• All errors are runtime errors. It's a step back from ObjC, and the aforementioned writing of `[obj foo:arg]` as `obj.foo_(arg)` gets me every time. Python is also more sensitive about None than ObjC is about nil, so you need more checks and forgotten checks blow up more often.
• I wanted to do more advanced stuff with CoreAnimation and PyObjC couldn't figure out how long to retain stuff (or it was a bug somewhere). I know how to debug such problems in ObjC (and they're rare since ARC), but having Python's GC and a large framework sandwiched in between made it hard.
• The app breaks when users replace macOS's old Python with their own, which lacks PyObjC support. I don't know how common that is, but I've been getting bug reports about it.
In the end I ended up rewriting large parts in ObjC, and the remaining Python code is slow and brittle.
These days there's Swift which isn't more laborious to write than Python thanks to type inference and ARC, but has compile-time checks, non-nullable types and first-class Cocoa interface.
Kivy is very interesting to me – I've been meaning to pick up Dusty Phillips's book about it.
I think PyQt is a more robust solution for GUIs, and it gives you cross-platform compatibility basically for free - although packaging is probably a bit harder.
There are mainly two challenges here:
- packaging (it’s a bit tricky to sort out, and bundling a full virtualenv is the best long-term option across OS releases)
- longevity (Ronald has been maintaining PyObjC on his own dime, and Apple seems to mostly ignore everything else in favor of Swift these days)
Grep and ask are there for POSIX compatibility, right?
I ask because I find the use of CamelCase like this for method names really off-putting.