[HN Gopher] Develop with Cocoa for Apple devices without using O...
___________________________________________________________________
Develop with Cocoa for Apple devices without using Objective-C
Author : quelsolaar
Score : 103 points
Date : 2023-09-11 14:44 UTC (7 hours ago)
(HTM) web link (felixk15.github.io)
(TXT) w3m dump (felixk15.github.io)
| quelsolaar wrote:
| Its absolutely crazy to me that both major mobile platforms don't
| have APIs that are available with bindings for all major
| languages. Forcing developers to use Java on android (A VM on a
| low powered platform), and ObjectiveC/Swift(Languages that are
| barely used on other platforms) is so hostile to developers.
| [deleted]
| no_wizard wrote:
| Given that Swift is open source, I'm surprised Android hasn't
| made it a 1st party alternative to using Kotlin.
|
| They could capture alot more developers this way, as learning 1
| language for both mobile platforms would facilitate more iOS
| only apps (there are many still even today) to get ported to
| Android.
|
| This may finally make Android tablets viable, as the app
| ecosystem for tablets isn't as good as iPadOS
| steve1977 wrote:
| Objective-C and Swift are used all over the Apple platforms,
| including desktop macOS. So ,,barely used" on other platforms
| is not really true.
|
| Also considering the number of iOS devices, those two languages
| are probably more usable in practice than for example C#, even
| if the latter is cross-platform.
| dreamcompiler wrote:
| "barely used on other platforms" clearly meant (to me anyway)
| barely used on non-Apple platforms. They're not terrible
| languages, but they're pretty uncommon outside the Apple
| ecosystem.
| steve1977 wrote:
| But the Apple ecosystem is huge. It's just much more
| consumer-oriented, in contrast to ,,corporate" languages
| like Java and C#.
| pjmlp wrote:
| Not kept up with the times?
|
| Since Android 5, with ART introduction, that Android uses a mix
| of AOT/JIT code.
|
| Java was invented for low end IoT, there isn't anything more
| low powered than anything in the last 20 years of mobile
| computing.
|
| Apple and Google should be cherished by not keeping the old C
| and C++ song of POSIX tunes going.
|
| As Rob Pike puts it, it is like only listening to David Cassidy
| records.
| wk_end wrote:
| Complaining about the JVM on Android ("a low powered platform")
| feels like a take that's about 10-15 years out of date. A
| modern Android phone is several orders of magnitude more
| powerful, however you might want to measure that, than the
| machines that Java was first designed for. And anyway, Android
| doesn't really use a VM anymore - it's been AOT compiling apps
| on installation for around a decade.
|
| There's about a billion things about developing on Android that
| are absolutely miserable. HLL-induced perf bottlenecks aren't
| usually one of them.
| quelsolaar wrote:
| How many Android devices are in service in the world? Whats
| the total power consumption of all Android devices? Shaving
| just 1% is probably a couple of coalfired power plants worth
| of CO2.
| geodel wrote:
| If no one use smart phone then you can probably bring down
| more than couple of coal fired plants. Isn't it great?
| astrange wrote:
| Embedded carbon from shipping too much DRAM is probably
| more of an issue.
| phendrenad2 wrote:
| I don't think GP's complaint is about Java and Swift being
| unperformant, I think the complaint is that you can't use the
| language of your choice easily. If we just had a C API we
| could interpret Ruby or Python with a standard interpreter.
| But instead, if you want to write a Ruby or Python mobile
| app, you need to translate objects between the language of
| your choice and Java/ObjC.
| iainmerrick wrote:
| Right -- Android does have a C API but it's a pain to use
| and really incomplete:
| https://developer.android.com/ndk/guides/stable_apis If you
| want to do anything else you need JNI which is an even
| bigger pain.
|
| I don't really understand why the Android team haven't made
| it easy to call any Java API from C, with auto-generated
| bindings or some such.
|
| I think they just don't believe in apps using native code,
| beyond the special case of games (note that pretty much all
| the native APIs are to do with low-level graphics and
| sound).
| rectang wrote:
| The interests of platform vendors and application developers
| are not aligned.
|
| Platform vendors seek to lock in developers and discourage
| development on competing platforms, while developers wish to
| leverage their skills portably across multiple platforms.
| sdflhasjd wrote:
| Google do maintain Flutter though, which is effectively a
| competitor.
| astrange wrote:
| Google isn't capable of aligning itself with its own mission,
| let alone locking in developers. They'll sooner release 10
| programming platforms invented for 10 new messaging apps.
| cellularmitosis wrote:
| This isn't so crazy. Apple doesn't want developers creating a
| bunch of slow, bloated, interpreted apps.
| akmarinov wrote:
| They really don't care. Source: every airline app ever, every
| Cordova or most RN apps
|
| As long as they tie into bringing Apple money- it's fair game
| Klonoar wrote:
| I mean, hang on there... Objective-C, while probably
| frustrating to get started with, is literally "just about C".
| Projects have been doing Objective-C interop for decades now,
| very similar to what is being done in the posted article. It's
| not really gated off at a programming layer, moreso in how
| Apple's been so frustrating about developing on non-Apple
| hardware.
|
| It's not exactly what I would call "hostile", language-wise.
| Swift, on the other hand, might be a bigger barrier...
| jwells89 wrote:
| Yeah, bindings for UIKit aren't actually all that challenging
| to write. There's quite a number of UIKit apps written at
| least partially in languages other than Obj-C/Swift.
|
| Android Framework on the other hand is not great in this
| department. Practically speaking it's just Java and Kotlin. I
| wish I could write Swift there because even if Kotlin is
| similar syntactically the JVM baggage can be irritating.
| dickersnoodle wrote:
| Use Swift.
| quelsolaar wrote:
| Shouldn't people have the choice you use what ever language
| they like and already know?
| jfb wrote:
| It means they'll end up fighting the platform, and that will
| lead to worse outcomes by many metrics.
| stalfosknight wrote:
| While I don't disagree with your sentiment, that is not a
| reasonable expectation for anyone intending to develop for
| Apple platforms. Apple has made it quite crystal clear for a
| long time now that Swift, and only Swift, is the One True Way
| going forward.
| georgeoliver wrote:
| Cool to see Eskil Steenberg's name pop up, his game dev diary was
| a very interesting read back in the day.
| quelsolaar wrote:
| Thanks! Mostly streaming and posting videos instead of writing
| now a days.
| darreninthenet wrote:
| Ooh thought I recognised that name - is Love still online and
| being developed???
| quelsolaar wrote:
| no its not. I am currently working on a new game.
| flohofwoe wrote:
| This is also what the "official" C++ API for Metal does
| (https://developer.apple.com/metal/cpp/), it's an automatically
| generated bindings wrapper which calls into ObjC runtime
| functions without an ObjC shim inbetween).
|
| Bit of a shame that this idea isn't extended to all system
| frameworks and not just C++ but also C bindings (official C
| bindings would make life a lot easier for all other programming
| languages).
|
| I also dabbled a bit with this idea by parsing clang AST-dumps of
| macOS system headers and generate C binding functions:
|
| https://github.com/floooh/objc-ast-experiments
|
| Unfortunately this is very brittle, and then also broke on ARM
| CPUs, I guess the shim code needs some ABI adjustments (famously,
| objc_msgSend has multiple "ABI shapes":
| https://www.mikeash.com/pyblog/objc_msgsends-new-prototype.h...).
| pavlov wrote:
| This is basically how the Cocoa-Java bridge worked 25 years ago,
| except of course Java has GC.
|
| The article makes no mention of memory management. ARC is a
| compiler feature, so I guess this C code makes a ton of calls to
| an nsobject_release() function for everything allocated in Obj-C
| world. The code example shown seems to be just leaking the
| NSString instance.
|
| Which platform doesn't have Clang? Why not allow the Obj-C
| compiler to take away all that C boilerplate and fragile retain
| counting gruntwork, and then wrap those calls in a concise C API
| that provides the exact interface your application needs? I don't
| really get it.
| [deleted]
| spullara wrote:
| Sadly the Java bindings were way easier to use than Obj-C but
| it undermined Steve's vision.
| pavlov wrote:
| I think the Oracle v. Google lawsuit (regarding Android's use
| of Java) validated Jobs's intuition that it wasn't a great
| idea to have somebody else's proprietary programming language
| as a first-party API.
|
| If Java had become the primary language for Cocoa, the path
| to Cocoa Touch and an iPhone App Store could have been much
| more complicated.
| jrmg wrote:
| Did you use them?
|
| I tried to and have _very much_ the opposite opinion about
| the ease of use.
| jfb wrote:
| Yeah, 1000% this. The Java bridge was a catastrophe, and
| Objective-C worked beautifully with Cocoa.
| spullara wrote:
| Oh there were rough edges but mostly because they abandoned
| them quickly but being able to use a great IDE to write
| code and have it all autocomplete was way better than
| having xcode open and the docs trying to figure out the
| APIs was painful.
| manmal wrote:
| Couldn't ARC be disabled, and autorelease be used instead?
| jshier wrote:
| Autorelease only works if you put the object in the
| autorelease pool. Some calling conventions also put it in the
| pool for you but if all you did was manage pools you'd leak
| memory.
| manmal wrote:
| I'm aware, is that an obstacle?
|
| > if all you did was manage pools you'd leak memory
|
| I'm not sure what you mean there.
| cellularmitosis wrote:
| > Which platform doesn't have Clang?
|
| Darwin/PowerPC :(
| klaussilveira wrote:
| I was curious about the leak on NSString too.
| quelsolaar wrote:
| This way you dont have to wrap by hand, and any time Apple
| releases a new API or makes a change you push a button and have
| a new wraper. Writing a wrapper also requires someone who knows
| Objective C.
|
| There are obviously things that could be refined, but for a
| first release it has proven to be very effective in production.
| pavlov wrote:
| But using the raw Cocoa Objective-C APIs via a wrapper...
| also requires someone who knows Objective-C? Because how else
| are you going to understand the API documentation?
|
| It seems that if you unleash this wrapper onto a C programmer
| who has never used Cocoa, you'll just be in a world of hurt
| with unexplained memory leaks and segfaults due to
| misunderstood object lifetimes.
|
| For example, class factory methods like +[NSString
| stringWithFormat:] will return an autoreleased instance. How
| will the C programmer know this convention if they've never
| used Objective-C?
|
| Practically nobody starts a new project on macOS / iOS that
| uses manual memory management instead of ARC, so you won't
| have a lot of documentation when you go down this path. The
| Apple documentation for the aforementioned stringWithFormat:
| method doesn't mention (anymore!) that the return value is
| autoreleased because that doesn't matter with ARC, but makes
| all the difference for someone using the C wrapper.
| miki123211 wrote:
| The API documentation is available in the header files. If
| you were to parse those, I'm pretty sure you could generate
| the docs for the C API automatically, just as Apple does
| for Swift. You'd need to do a fair bit of search-and-
| replace to get the function and type names right, but the
| API surface is finite and it doesn't change that often. If
| you were willing to put a good amount of work into a
| generator, you could get it to a state where it would be
| able to fully parse all of the Apple SDKs.
|
| There's no magic in ARC, it's all just calls to retain and
| release that the compiler synthesizes for you
| automatically. If you have the headers, you can do what it
| does and figure out which methods return objects that need
| to be manually released. If you were generating bindings
| for a language with RAII, like Rust or C++, you could
| create a bunch of wrapper types and give them destructors,
| the best you can do for C is adding an extra paragraph in
| your docs.
| LuckyBlade wrote:
| >It seems that if you unleash this wrapper onto a C
| programmer who has never used Cocoa, you'll just be in a
| world of hurt with unexplained memory leaks and segfaults
| due to misunderstood object lifetimes.
|
| This is true for _every_ API under the sun. If you just use
| it without reading the documentation or understanding the
| design philosophy, you 're alyways in a world of hurt.
|
| The same things that are true for Obj-C are true for the
| wrapper, it just lets you use the API in C. No more, no
| less.
| Klonoar wrote:
| _> If you just use it without reading the documentation
| or understanding the design philosophy_
|
| They literally covered this point for you:
|
| _> The Apple documentation for the aforementioned
| stringWithFormat: method doesn 't mention (anymore!) that
| the return value is autoreleased because that doesn't
| matter with ARC_
|
| It is no secret that documentation surrounding the "old
| ways" of Apple dev is a pain in the ass to find.
| pavlov wrote:
| That's the point. To use this wrapper correctly, you need
| to know how Objective-C works and you need to be able to
| read Obj-C code to understand the documentation.
|
| In fact you need to know quite a bit more about Obj-C
| details than the average iOS programmer because you're
| doing manual memory management rather than compiler-
| assisted ARC (automatic reference counting).
|
| So I don't really see who this is for. The person who has
| to learn Obj-C but must pretend not to know it to please
| the boss who insisted on plain C?
| tambourine_man wrote:
| I'm not an iOS/Mac developer, but aren't Swift-only APIs common
| these days?
|
| How would this binding work in such cases, if at all?
| tarentel wrote:
| SwiftUI related things might be the only swift-only API apple
| is actively working on as far as I know. If there's another one
| I don't remember it. Almost everything they release will be
| accessible in obj-c.
| Klonoar wrote:
| They've slowly started doing Swift-only pieces - e.g, App
| Intents are also Swift-only, WatchKit complications (I
| believe), CryptoKit
| (https://developer.apple.com/documentation/cryptokit/), etc.
|
| (It's not a big blocker to still be tied to Objective-C IMO;
| I'm mostly just responding to the _" might be the only swift-
| only API apple is actively working on_" line.)
| jshier wrote:
| Nearly all "new" frameworks have been Swift-only over the
| last few years. Like you mention, CryptoKit and widgets,
| but also Combine, the entirety of SwiftUI, and even smaller
| things like the ProximityReader framework they released
| with iOS 15.4. They're even rewriting Foundation using
| Swift while exposing an Obj-C compatible ABI. Of course,
| any new API in frameworks which are already Obj-C are
| usually written in Obj-C and exposed to Swift. This means
| new Obj-C code will be written for years to come.
| flohofwoe wrote:
| As far as I'm aware only visionOS has some Swift-only
| frameworks. All the actually important frameworks for macOS and
| iOS development are still callable from ObjC.
| akmarinov wrote:
| There's a whole bunch of frameworks that are Swift only like
| SwiftUI, WidgetKit, SwiftData, MusicKit, SharePlay,
| DeviceActivity and others and can't be called from ObjC
| meepmorp wrote:
| But you can write Swift code that can be called from objc,
| right? Could you write a wrapper/shim in Swift for "object
| c" that you'd then call using the method outlined in the
| article?
| akmarinov wrote:
| You can yeah. With Apple's older frameworks, you could
| use either though. It just shows that they're gradually
| moving away from ObjC
| so898 wrote:
| This just like the JSPatch which creates a JS wrapper use Cocoa
| API in javascript environment. I think to make the code compile
| and run for multiple platform, the top level API is the key, not
| the some-kind-of Objc-based-c-runtime. Flutter is a good example.
| Chromium is a better example. What this shown is more like the
| failing C# for Apple. I have no idea why so many devs used this,
| but with the end of Visual Studio for macOS, no more C# for Apple
| platform.
| hu3 wrote:
| > but with the end of Visual Studio for macOS, no more C# for
| Apple platform.
|
| On the contrary!
|
| .NET has been cross-platform for years now and runs fine in
| Linux, Windows and macOS.
|
| Visual Studio for Mac was a legacy piece of software and was
| promptly replaced by either Jetbrains Rider or VSCode +
| Microsoft's C# Dev Kit.
|
| If anything, this transition will foster C# in macOS since
| newbie devs wont stumble upon by accident on the horrible
| experience that the legacy IDE had to offer.
| miki123211 wrote:
| I'm surprised the authors didn't go for parsing the headers that
| Apple ships with their SDKs instead of extracting method and
| class names from the runtime.
|
| That would solve many of their issues, including missing argument
| names, type information for arguments and return values and
| access to iOS frameworks on Mac.
|
| I'm not sure how difficult that would be to accomplish, though,
| considering how macro-heavy C often is.
| quelsolaar wrote:
| We have considered parsing both headers and documentation in
| order to make the generated API prettier. This is the first
| release, so we want to see if there is interest, but yes there
| are lots of things we could do to expand the project (Auto
| documentation in header files, other language bindings...)
| miki123211 wrote:
| I wonder how they deal with things like creating user interfaces
| (and the outlet/action pattern), passing blocks, exceptions or
| creating their own classes, something that you have to do quite
| frequently because of Apple's heavy use of the delegate pattern.
| The runtime does provide class creation functionality, so it's
| very much doable in C, but it requires a lot more code than doing
| it the official way. Creating classes in this manner is also an
| imperative action, so you need to keep track of whether your
| class has already been registered and return the existing
| instance if necessary.
| mpweiher wrote:
| Those who don't understand Objective-C are bound to reinvent
| it...badly.
|
| "... you could even use the generated API with Lua, Python, Ruby
| or JavaScript"
|
| Guess what, all these have Objective-C bridges, usually multiple
| ones, because the combination of being just a thin shim on top of
| C as well as that thin shim being essentially a Smalltalk with
| full dynamic messaging and runtime introspection + intercession
| means interop is Objective-C's bread and butter.
|
| No C code generation required.
|
| This should be no surprise because that was exactly the stated
| goal of Objective-C, and they achieved it admirably. If you think
| Objective-C is a closed, vendor-specific language like Swift, you
| truly don't understand it. At all.
|
| Someone once described Objective-C as "COM with language support"
| and that's pretty accurate.
___________________________________________________________________
(page generated 2023-09-11 22:00 UTC)