7 ms·
Develop with Cocoa for Apple devices without using Objective-C
- quelsolaar 3y agoIts 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.
- Klonoar 3y agoI 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 3y agoYeah, 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.
- deleted 3y ago[deleted]
- wk_end 3y agoComplaining 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.
- phendrenad2 3y agoI 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 3y agoRight -- Android does have a C API but it’s a pain to use and really incomplete: https://developer.android.com/ndk/guides/stable_apis 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).
- pjmlp 3y agoYou don't need to wonder, it is quite explicity mentioned on the NDK documentation. "The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C++. For certain types of apps, this can help you reuse code libraries written in those languages." -- https://developer.android.com/ndk https://developer.android.com/ndk "The NDK may not be appropriate for most novice Android programmers who need to use only Java code and framework APIs to develop their apps. However, the NDK can be useful for cases in which you need to do one or more of the following: - Squeeze extra performance out of a device to achieve low latency or run computationally intensive applications, such as games or physics simulations. - Reuse your own or other developers' C or C++ libraries. " -- https://developer.android.com/ndk/guides https://developer.android.com/ndk/guides There is also the security aspect, why they discourage the use of those languages for full blown applications.
- 3y ago
- steve1977 3y agoObjective-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 3y ago"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 3y agoBut the Apple ecosystem is huge. It’s just much more consumer-oriented, in contrast to „corporate“ languages like Java and C#.
- rectang 3y agoThe 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.
- cellularmitosis 3y agoThis isn’t so crazy. Apple doesn’t want developers creating a bunch of slow, bloated, interpreted apps.
- akmarinov 3y agoThey 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
- pjmlp 3y agoNot 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.
- no_wizard 3y agoGiven 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
- pjmlp 3y agoAndroid has 70% of the world market, there is no reason to care about Swift. Also Kotlin and Android Studio are mostly developed by JetBrains that is in bed with Google for Android tooling, if anything I expect more Google acquiring JetBrains than supporting Swift on Android.
- cxr 3y agoObjective-C has been open source for even longer, and Cocoa and the associated mobile toolkits eminently clonable. I'm rather more surprised that Google didn't make an 80/20 iOS compatibility toolkit 15 years ago. If they didn't do that then when iOS was dominating the hearts and minds of pretty much every developer behind any noteworthy mobile app, then I wouldn't expect them to make Swift a first-class priority today, when Android has basically "won" on the global scale.
- dagmx 3y agoIt's really trivial to use ObjC from any language with a CFFI. and in turn really trivial to expose Swift to ObjC as well, so to other languages. Just some examples of bindings: Python https://pypi.org/project/pyobjc/ https://pypi.org/project/pyobjc/ Rust https://docs.rs/objc/latest/objc/ https://docs.rs/objc/latest/objc/ C# https://learn.microsoft.com/en-us/xamarin/ios/get-started/objective-c-developers/primer https://learn.microsoft.com/en-us/xamarin/ios/get-started/ob... Javascript https://www.npmjs.com/package/objc https://www.npmjs.com/package/objc
- eschaton 3y agoWhat’s hostile about trying to provide the best possible APIs for a platform according to the vision of the people creating those APIs?
- pavlov 3y agoThis 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.
- klaussilveira 3y agoI was curious about the leak on NSString too.
- quelsolaar 3y agoThis 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 3y agoBut 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.
- georgeoliver 3y agoCool to see Eskil Steenberg's name pop up, his game dev diary was a very interesting read back in the day.
- quelsolaar 3y agoThanks! Mostly streaming and posting videos instead of writing now a days.
- darreninthenet 3y agoOoh thought I recognised that name - is Love still online and being developed???
- quelsolaar 3y agono its not. I am currently working on a new game.
- tambourine_man 3y agoI’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 3y agoSwiftUI 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 3y agoThey'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/ 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 3y agoNearly 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 3y agoAs 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 3y ago
- so898 3y agoThis 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 3y ago> 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.
- flohofwoe 3y agoThis is also what the "official" C++ API for Metal does (https://developer.apple.com/metal/cpp/ 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 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.html https://www.mikeash.com/pyblog/objc_msgsends-new-prototype.h...).
- pjmlp 3y agoAs mentioned on the Swift talk at CppNow 2023, most of the C bindings are actually C++ with extern "C", and Apple would rather write less of them than more of. "CppNow 2023:Introducing a Memory-Safe Successor Language in Large C++ Code Bases" https://www.youtube.com/watch?v=lgivCGdmFrw https://www.youtube.com/watch?v=lgivCGdmFrw
- dickersnoodle 3y agoUse Swift.
- quelsolaar 3y agoShouldn't people have the choice you use what ever language they like and already know?
- eschaton 3y agoWhy? That would constrain Apple’s API design to only that expressible in the common subset of languages developers might realistically want to use.
- newZWhoDis 3y ago[flagged]
- stalfosknight 3y agoWhile 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.
- jfb 3y agoIt means they'll end up fighting the platform, and that will lead to worse outcomes by many metrics.
- MBCook 3y agoYes. And you can. Obj-C and Swift both have the ability to interop with anything that can speak C. But if all you want to do is not use Obj-C then Swift us the 100% supported official path. No need to hack your own wrapper.
- miki123211 3y agoI'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 3y agoWe 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 3y agoI 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.
- astrange 3y agoYou should not use exceptions in ObjC unless it's truly exceptional; most system code (and all ARC code by default) is not exception-safe and will leak objects if thrown through. And Swift will insta-crash if it sees one.
- mpweiher 3y agoThose 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.
- newZWhoDis 3y ago[flagged]
- kccqzy 3y ago> 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. Exactly. In fact sometimes in lieu of shell scripts I write simple utility JavaScript files using Objective-C APIs and run them under osascript. For Python, the easiest way to copy a file while not using twice the disk space (using reflinks) is still using the Objective-C API: https://github.com/RhetTbull/osxphotos/blob/20ef78bbd45a678772f3473242cc29298fc32812/osxphotos/fileutil.py#L137 https://github.com/RhetTbull/osxphotos/blob/20ef78bbd45a6787...
- whiddershins 3y agoCan you explain the JavaScript api more? Are you talking about a webView or something else. Edit: oh I see what you are talking about. The osascript aspect was what I wasn’t getting.
- kccqzy 3y ago
- KerrAvon 3y agoThe title is incorrect -- this is still using Objective-C, it's just obfuscating the syntax for no really good reason.
- quelsolaar 3y agoNo its not. All Objective C objects can be assessed using a C API. This C api is very hard to use, so tecnically its nicer C code wrapping a bad C API.
- eschaton 3y agoIndeed. There’s no good reason for this to exist.
- lisper 3y agoIs an analogous thing possible for Swift? The writing seems to be on the wall for ObjC in Cocoa.
- frankus 3y agoThis may or may not apply to OPs app, but for mobile-first apps with a broad audience, having an identical appearance/interaction model across competing mobile platforms is a bug, not a feature. Or maybe not exactly a "bug" but at least an unfortunate tradeoff because your org lacks in-house expertise on one or more of the target platforms. The case of a single person using many apps on a single mobile platform is just so much more common than the case of a single person using your app on multiple mobile platforms that it makes far more sense to hew to the platform idioms at the cost of cross-platform consistency. An obvious exception might be something like Slack, where it's common to use both the mobile app and the web app (either directly or via an Electron-like wrapper), but calling Slack "mobile first" is also a stretch.
- factotvm 3y agoSlack is web-first at best. It has nearly zero platform conventions, at least on desktop. (It’s been some time since I’ve used the mobile app.) A quick couple of examples: multi-selection and drag-n-drop, both all but broken on desktop.
- elcritch 3y agoInteresting project, though I'd rather just use Obj-C. I guess if you wanna use it in something like JavaScript or Lua it'd make sense to have C as a bindi g layer. > https://gamepipeline.org/betray.html https://gamepipeline.org/betray.html Interesting, I've been using a similar project for Nim lately: https://github.com/treeform/windy https://github.com/treeform/windy It's surprising how simple Obj-C interaction is compared to Java JNI or something. Here's the Obj-C interop for Windy: - macdefs: https://github.com/treeform/windy/blob/master/src/windy/platforms/macos/macdefs.nim https://github.com/treeform/windy/blob/master/src/windy/plat... - macro shims for Obj-C messages: https://github.com/treeform/windy/blob/master/src/windy/platforms/macos/objc.nim https://github.com/treeform/windy/blob/master/src/windy/plat...
- dagmx 3y agoI'm not sure I understand the advantage here other than avoiding a few `.m` files? The maintainers will still need to know ObjC to understand the Cocoa calls, and this presumably removes a lot of the ObjC niceties in the process. And now you have an extra layer to maintain, as well as resource allocations to maintain, that ARC would take care for you. Is all the overhead worth it, over just learning to put a few square brackets around the place? The blog does mention stuff like bindings to other languages, but since ObjC is just C, that's no easier or harder really than before.