[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)