Hacker News new | ask | show | jobs
by lapcat 856 days ago
I use Objective-C exclusively (no Swift) in my App Store apps.

I wrote a Swift app for a hobby/free project a few years ago and regretted it. They changed the language and deprecated some of my code, which isn't easily replaceable without a significant rewrite. The project now compiles only in Swift 4 and will die when Swift 4 support is removed from Xcode.

I see no reason to use Swift. The compiler is slower and buggier. The debugger is slower and buggier. C interoperablity, while it exists in Swift, can be very painful. And I don't actually ship any bugs that Swift could have theoretically saved me from. I see no gain in switching.

People have been telling me since 2014 that every line of code I write in Objective-C is "technical debt". I continue to laugh at them and ask them to compile Swift code they wrote in 2014.

Of course if I had to get a job, it would be a different story, but I own my company, so I can do whatever I want.

7 comments

As a counter-anecdote from someone who also runs their own company, I began dabbling in Swift in 2014. I held off on full Swift adoption until after the big API renaming that happened with Swift 3, so language migrations haven’t been a big deal. The compiler is slower, but I can still do a clean build in 43 seconds.

Maybe I’ve had a good experience because I’m not working on a FAANG project with a million lines of code, but that’s all to say there are shades of grey, and you have to consider what you get in exchange for Swift’s compiler and evolution overhead.

Personally, I’ve found Swift helps avoid entire categories of bugs that crop up in ObjC, like accidental nil messaging. Generics have allowed me to avoid duplicate implementations. Now SwiftUI has allowed me to implement things in hours what would have taken me days in UIKit. I could go on for a while, but those are off the top of my head.

If you find yourself enjoying ObjC, by all means keep using it. Or C. Or Pascal. Or Lisp. There are tons of different ways to accomplish the same thing, but that doesn’t account for extra-hours and bugs it takes to get there.

> If you find yourself enjoying ObjC, by all means keep using it. Or C.

I didn't say I enjoyed ObjC. That's not really how I choose my tools. It's a job. The choice is utilitarian.

> Or Pascal.

I seem to recall enjoying Pascal somewhat, though that was a very long time ago.

> Or Lisp.

I definitely recall not enjoying Lisp. Not at all. Yuck.

> that doesn’t account for extra-hours and bugs it takes to get there.

If Swift helps you, that's great. I'm just writing about my experience. For me, it doesn't help. I'm certainly not deliberately avoiding a tool that would help me. I do write my share of bugs, but I rarely write the type of bugs that the Swift compiler would catch, and I never ship them. YMMV

I'm not intending to offer advice of any kind to others. I'm not much for giving or taking advice. And like I suggested, if I needed to find a job, then I'd probably have to go all-in on Swift. My goal, though, is to never get another job for the rest of my life. ;-)

> I didn't say I enjoyed ObjC. That's not really how I choose my tools. It's a job. The choice is utilitarian.

Given C is faster and more mature than ObjC, why aren’t you writing everything in pure C and objc_msgSend?

> Given C is faster and more mature than ObjC, why aren’t you writing everything in pure C and objc_msgSend?

TBH your question feels trollish, but I'll respond anyway.

Objective-C code does compile to objc_msgSend calls. Perhaps you meant getting the method implementations directly and calling them instead?

Objective-C is 40 years old. How much more mature does it need to be?

You said you make the utilitarian choice. By using C everywhere, you can use an even faster compiler that doesn’t insert those calls for you. So why don’t you?
> By using C everywhere, you can use an even faster compiler that doesn’t insert those calls for you.

In the previous comment you said I should use objc_msgSend, now you say I shouldn't. Make up your mind. ;-)

Anyway, I'm using AppKit and UIKit to write apps. The API is Objective-C. That's why I write Objective-C.

Whatever the heck you're talking about—you appear to be confused, so I don't know what exactly you mean technically—it certainly sounds like premature optimization, which is a waste of time and not the correct utilitarian choice. My Objective-C code is not "slow". Could it be infinitesimally "faster" in way that's not even perceivable by the user? Perhaps, but who cares?

Because of all the downsides. The utilitarian choice is about practicality, not pure performance. This line of questioning is silly.
I built an iOS app alone, from the ground up, in Objective-C. This was after I left Apple, where I mostly used C++. I hated Objective-C less than I expected, and the app was functional and reliable.

Then I built an iOS app for a consumer-electronics company alone, from the ground up. I learned Swift and wrote the whole app in it. I liked it a lot. Once I had the language down, I was very productive and able to implement almost any change that management requested in a few days at most.

SwiftUI, however, is a very different story. It's a half-assed, often brain-dead environment that has made building my own application from the ground up PAINFUL. Not only has it taken months to do what should have taken weeks, but SwiftUI and the attempted "reactive" paradigm it's supposedly optimized for are so full of holes that Apple's recommended practices simply don't work. "One source of truth" my ass; SwiftUI and the absurdly incomplete observation framework it relies on make that impossible.

I usually blame myself for just not having read enough, but with SwiftUI my research has far too often concluded with a finding that, "Oh yeah, that doesn't work."

former Mac dev here, and completely agreed. Refactoring an app because someone else decided to change the language is a bridge to far. And if they do it this time, they'll do it again. Meanwhile the ObjC compiles.

--- Rant - With Swift Apple shifted dev power to themselves. Having gotten fat on the open world, they've backed away from every 'Open' technology they can, and replaced it with their own, ( presently all the way to CPU architecture). Yes, they are giving tremendous powers, but have they also crafted the One Ring.

Yes, but it is common for new languages and frameworks for there to be lots of change in the first few version. Then it matures and settles down. AFAIK Swift is not regularly making large changes, anymore.
Go wasn’t that way, in some respects it is a language design choice whether you want to retain compatibility
Foundation is now open source at least
After years of obj-c I wrote a rather larger app on Swift 1.1. I'll never forget the pain of upgrading to each new version of Swift. And my god, the pain of early swift string manipulation. 100% technical debt annually.
If there’s one lesson to take from Swift 1 and 2, it’s that Apple is comfortable launching beta APIs that can undergo massive churn. It’s why I avoided SwiftUI for the first few years, and now why people would be wise to do the same for SwiftData.
Same with Google. When they announced that Compose was now "stable" I laughed out loud and said "they just slapped a 1.0 version on it, didn't they?". And yes they did. We're a lot of releases later and it's still no fun to debug weird-ass issues. Last week I had two textfields, and both of them had focus at the same time!
> Apple is comfortable launching beta APIs that can undergo massive churn

You see this as a consumer, too. Apple very much moves on from old hardware compared to Microsoft.

Honest question: what exactly did you expect when adopting a brand new language? Apple were explicit that they would make breaking changes. Besides, would you rather be stuck with Swift 1 forever? It was pretty meagre in retrospect.
You’ll have an increasingly harder time adopting new Swift-only APIs

For example OCR - you can use the old low quality Vision API but the new ImageAnalyzer can’t be accessed via ObjC and requires custom bridging. More and more new APIs will be Swift exclusive

I'll cross that bridge when I come to it.
In these cases I like to use the malaphor we'll burn this bridge when we get to it :) Because that's how these changes feel like.
*bridging headers
absolutely the same here.

the problem with Swift is that it is a systems programming language and not an app-development language. far to cumbersome, complicated and unproductive for writing apps.

What makes it a systems language and not an app-development language?
different buzzwords
This is objectively false. It's first and foremost an app development language. In fact this is a common complaint, that Apple pushes too many features that are specific to app development and now SwiftUI.
What's an example of an app development language?
> “Swift is … not an app-development language.”

Huh? As compared to Objective-C, with Swift you generally get more done with less boilerplate, less repetition, and certainly far less semi-colons and square brackets.

If you consider ObjC to be an app-development language, I can’t really imagine how Swift can’t be one?

I started using Swift right away in 2014 and worked on several large projects written in Swift 2, 3, 4. Of the three or four large migrations I had to perform, the worst one still took less than a day - unless your Swift 4 project is enormous, you should be able to migrate it to Swift 5 before lunch time, the differences are really minimal.

Surely it's a good thing that a young language evolves, you can't improve without changing. And Apple were very clear about the fact that there would be breaking changes.

You can of course insist on using Objective C if you prefer it, but that closes the door to most of the new APIs that are being added by Apple, which seems like a very steep price to pay for the privilege of using a legacy language.

Me, knowing my own code: "isn't easily replaceable without a significant rewrite"

You, knowing absolutely nothing about my code: "you should be able to migrate it to Swift 5 before lunch time"

(In this respect, yours is such a sterotypical HN comment. "I could build [whatever] over a weekend.")

Moreover, even if your baseless, overconfident assertion were true, it's now about 6 hours until lunch time, and I'd rather not waste that time on a free hobby project just to make the damn Swift compiler happy.

> that closes the door to most of the new APIs that are being added by Apple, which seems like a very steep price to pay

I haven't needed anything that requires Swift, so there's been no price paid. I'm doing great. No problems! Swift proponents seem to have to tell themselves that I'm suffering in some way by continuing to use Objective-C, but I'm not suffering at all.

Regardless of language, I usually avoid new Apple API, because it tends to be half-baked and buggy.

The source breaking differences between swift 4 and 5 are very few, and quite mechanical. Most of them should be adequately handled by the migration assistant, did you try that? If it’s open source, I’m happy to take a look.
I already know exactly what the issue is. I don't need your condescension.
I offered help, not condescension. In my experience migrating to swift 5 has been exceptionally painless, so if you find it onerous I was offering to assist you.
It's condescension because you continue to refuse to believe what I'm saying, and you keep insisting that something difficult is easy.

Moreover, if I needed help with a Swift issue, I would go to my many friends and associates in the Apple developer community. In fact, I've discussed the issue with some members of the Apple Swift engineering team, and I have an open bug report that Apple hasn't addressed. The very last person in the world I would consult about a programming issue is a random, condescending HN replier.

> C interoperablity, while it exists in Swift, can be very painful

Interesting, that hasn't been my experience. I'm curious, what have you ran into that was painful?

If I recall correctly you have to make a separate module with the bridging headers, but the first problem is that I can't remember exactly of the syntax of that file.

The second is that it's a lot of code and files to make when we only have one import to hack something quickly. For a full library it's probably a very cool feature though.

The third one is more related to my use case. I made a binding with a non-C codebase, and Swift cannot directly import C functions AFAIK, so I had to write C code in addition to the Swift one to make headers. It's not impossible, but it does take time to write all of that in a third programming language.

The fourth problem is related to library imports. In SPM, you either import a system library, or an xcframework. If your app targets any non-Apple platform, xcframeworks are not an option, so if you made a binding to your own lib that's annoying as it is probably not installed while you're building. And even if you're targeting Apple platforms, making an xcframework without Xcode is not well documented.

I probably missed a few problems as my experience is not very extensive, and there are probably better ways to achieve some of the things I wanted to do, but there isn't much documentation about all of that online anyway as far as I saw.

Alright yeah, I can concur with the packaging of the library so that it would eventually link and be accepted by the App Store which is surprisingly not the same set of requirements. It's just that I didn't completely chalked this up to Swift interop with C specifically but more the fact that multiple things Apple side need some jumping-through-hoops and that's just one of them.

I solved that through importing the dependency with Conan, and having extra steps running afterwards that would perform some quick and dirty lipo, xcodebuild and PlistBuddy stuff. It just wasn't that complicated, and only a few headscratches, but then it'd work and there was no need to touch that again, but situations may vary and I get that it could be painful in some cases.

I'm not op and it's been many years since I tried but back in the early days of Swift interop with C worked great until it didn't and it was very difficult to figure out what was going on because the debugger might as well have not existed.
Not aimed at you particularly, but I've noticed more and more of the technical discussion on HN turn into "I don't really use it, but here's my many years old experience / non-user observation", which is mostly just confusing to people trying to leadn.

You don't need to justify op with old anecdotes, people want to know what the issues are today, if any. At least that's what makes this website valuable for me.

Do you expect people to periodically repeat failed experiments just so they can provide you with up to date information? You are always free to ignore it.

In any case, this particular observation is timeless: language bridges always have trolls under them. Maybe your project can get away with using the bridge anyway, but maybe a highly critical API gets locked out because the bridge deals poorly with variadic arguments or object lifetimes or templates/generics or nested objects or latency/overhead assumptions or.... whatever, and the troll conks your schedule on its head. Try to minimize exposure and prioritize steps to de-risk the bridge.

Do you expect people to periodically repeat failed experiments just so they can provide you with up to date information?

Not OP, and I for one don't, but noting the age of the reported experience would be valuable. I have also noticed the "stale cache" problem. It leads to confusion and misunderstanding.

Definitely makes sense. In defense of the previous comment I made though, the debugger is only marginally better than when Swift first came out. That's regardless of whether or not you're interoping with C. It's still a terrible experience compared to what Obj-C provided.
Sockets come to mind.