Hacker News new | ask | show | jobs
by sharikous 1046 days ago
Question: is Objective-C post 2.0 being actively maintained outside of Apple?

Can I use the new features that Apple added in cross platform projects or open source environment like this?

I loved Objective-C very much (yes, really) and I'd like to continue using it after Apple phases it out

4 comments

The clang/LLVM Objective-C compiler is open source. You can use the same bleeding edge compiler for iOS 17 on Linux for example. So you can use features like Automatic Reference Counting, blocks, etc no problem.

The problem is the frameworks (Foundation, UIKit, AppKit, etc) are closed source. So you either need to create your own frameworks or use something like GNUstep.

Previous posts describe Swift in a state of flux, while Objective-C is more stable in most areas. It would not appear that phasing out Objective-C would even be possible.

https://news.ycombinator.com/item?id=35914330

Apple has the largest Objective-C code based in the world (I would assume).

It’s going to take them a long time to covert it. So I don’t see them dropping it anytime soon.

It’s not recommend for new code (in Apple land) and they’re already starting to make features Swift-only.

But they won’t stop shipping it any time soon.

> It’s not recommend for new code (in Apple land) and they’re already starting to make features Swift-only.

That's a real shame because FFI language bindings to Objective-C frameworks are amazingly simple to do with Objective-C. You basically create low-level C ABI bindings to objc_msgSend and about 40 other routines (e.g. class_getName). The latter bindings are principally for introspecting the class hierarchy and acquiring references to opaque class and method implementation pointers. method_getTypeEncoding returns a text-encoded type signature for a method. And objc_msgSend itself is a magical variable argument function for invoking arbitrary methods on arbitrary objects (including classes, which are objects themselves).

With that small set of C ABI bindings you can generate strongly typed bindings to all the many thousands of Objective-C framework and library interfaces, system and third-party. I did this for Lua and it works beautifully. And you can just as easily define new classes and methods and wire them up to the host language (Lua, Python, Java, Rust, etc), though I haven't needed to do that just yet. In my case this is all done dynamically at runtime, except for the ~40 required static C function bindings.

The only difficult part was binding objc_msgSend. You could use libffi, but in my case I wrote a script to statically generate a permutation of Lua/C binding functions with up to 6 arguments, any 2 of which could be doubles instead of scalars, and either a scalar or double return value. Atop those bindings sits a small Lua library which, using the other ~40 Lua/C function bindings, implements a type-safe bridge for the entire macOS Objective-C platform, GUI frameworks and all, modulo a small number of niche edge cases (e.g. IIRC there's a special Objective-C ABI for directly returning small structures which my objc_msgSend bindings don't implement, but I haven't run into those cases and my Lua bridge code would throw an error if I tried).

Because Objective-C itself uses reference counting, it plays well with any GC environment or lack thereof.

I'm sure Swift is a nice language, but there are many nice languages, and Objective-C makes language interoperability downright dreamy.

Wow, so I could write an MacOs app just with Lua + your bindings ?
Almost. You could start the main loop ([NSApp run]), but the reverse bridge would need to be implemented as the 'run' method blocks so you need event callbacks to be able execute any Lua code within the main loop. And for event callbacks you basically need the ability to create C Blocks (Apple's bespoke C/C++ closure primitive) to forward calls into Lua, and I just haven't done that yet. (It's simple in principle.)

I originally had no inkling that Objective-C was so easy to write bindings for. I was vaguely familiar with its message passing architecture, but didn't appreciate the low-level implications--the potential ABI power (not just API) that came from foregoing static linking. I started my app hoping to not have to write many bindings to macOS interfaces, partly because I wanted to port it to Windows and Linux. I'm using the Yue GUI toolkit, which made it easy to bring up a simple Lua app without having to understand anything about platform GUI frameworks.[1] I wrote a whole slew of Core Foundation (plain C) Lua bindings for little things like property file integration, hoping to avoid dealing with Cocoa APIs. But eventually all the little limitations of Yue (many now resolved) and my need for deeper desktop integration forced my hand.[2]

My Lua bridge is definitely not the first, but most (all?) such projects are dead or dormant. Some might still be usable with some tweaking; I don't think out-of-the-box, though, which IIRC helped push me toward writing my own. My app is currently closed source. I've open source'd parts of it already (e.g. early version of a suite of LPeg parsers for X.509-based formats, posted to the Lua mailing list), but my Lua/Objective-C bridge is spread across several files (e.g. the objc_msgSend thunk permutation and code generator) and not something that can be easily dumped into a standalone form without a little refactoring. If I have the opportunity to do so, I may in the future. I just don't like publicly releasing anything that isn't usable out of the box. But if you contact me by e-mail I'd be happy to share the code: william@25thandClement.com or william@keymux.com.

[1] Yue also has JavaScript bindings, and both sets of bindings rely on a shared C++ framework, so Yue provides equal treatment to C++, JavaScript, and Lua applications.

[2] My app, KeyMux, is for integrating common open source toolchains and work flows with hardware-protected RSA and ECC keys, including the Apple T2 Secure Enclave, for which I had to write static C bindings to Apple's Security framework, the low-level public interfaces to which are straight C interfaces. So in truth I would have had to write Core Foundation bindings one way or another as Security heavily uses CFArray, CFDictionary, CFNumber, and CFString. But those bindings probably would have been much simpler and more basic if I knew I would be able to lean on the Objective-C frameworks (e.g. Foundation, AppKit) for other desktop integration tasks. All of this--the whole world of desktop GUI programming, not just Objective-C--was new territory for me, so at least I picked up a wealth of knowledge on my circuitous journey.

Thanks for the detailed explanation and the contact offer <3
> Question: is Objective-C post 2.0 being actively maintained outside of Apple?

Yes as part of the GNUStep project [1]. You can compile Objective-C with Clang for any platform, including Windows, and link with the GNUStep Obj-C runtime. The big problem is outside of GNUStep and macOS you won't have any frameworks - not even NSString.

> I loved Objective-C very much (yes, really) and I'd like to continue using it after Apple phases it out

You're not alone. Unlike C++, Obj-C was a reasonable OO extension to C. It's a shame the language never received more love.

[1] https://github.com/gnustep/libobjc2

You could also use something like ObjFW to get some of those nice classes.
well, the one positive thing about apple phasing out Objective-C is that enthusiasts may be more motivated to work on GNU Objective-C to catch up, also considering that doing so is no longer a runaway target.