5 ms·
Actually I disagree. Since I started writing new apps exclusively in Swift, my apps have crashed exactly zero times according to Fabric/Crashlytics. I adopted
by 4eleven7 8y ago
Actually I disagree.
Since I started writing new apps exclusively in Swift, my apps have crashed exactly zero times according to Fabric/Crashlytics.
I adopted day one, never looked back.
It is an incredibly safe language when used correctly (never force unwrap for example, ever).
While previously my Objective-C apps did have numerous crashes in them. I took on an Objective-C contract recently, and it was a nightmare.
Of course, mixing with Objective-C may actually be the cause of issues or crashes? Who knows.
- gurkendoktor 8y agoAs a counter-example, the macOS Dock was rewritten in Swift in macOS 10.12, and Mission Control was super buggy for me then. I'm not blaming this on Swift, most rewrites are buggy at first. And it never outright crashed, but getting stuck in inconsistent states is not much better. In fact, I would argue that this new trend of defensive programming in Swift will make software worse in the long run. We had a tradition of sending crash reports back to developers. If everyone now starts their methods with `guard let param = param else { return }`, software will silently fail on end user devices, and everything will look fine in Crashlytics/App Store Connect. I'm not saying that this is what your apps are doing. But I know that Apple bragged about their record low in crash numbers at a time when I ran into different glitches across all of their apps every single day. It's a flawed metric.
- jchb 8y agoThe idea of an option type (Optional in Swift) is to use it only for a variables truly assume a "none" value at some point. With the guarantees of such a type it is easier to reason about the correctness of a program - compared to Objective-C where a pointer anywhere may be null at any time. Optional shouldn't be used for most variables and parameters. `guard let param = param else { return }` should be something pretty rare. I would mostly expect to see that for weak self variables in completion blocks. Also, take into account that in Objective-C you can send any message to a nil pointer, and the result will be nil or 0 (for scalar types), as defined by the language standard.
- wool_gather 8y agoThe point stands, however, that just because developers are forced to handle the `nil` somehow, doesn't mean they're handling it in a sensible way that makes for consistent UX. Crashing sucks from a user perspective, obviously data corruption is even worse, but just throwing up your hands and returning early from a view controller method doesn't really do anything for the user either. I generally find it useful to have the concept of Optional, making me think about "could this thing be missing?" explicitly. But I've started to wonder if it is, rather than "preventing an entire class of bugs", actually just making them pop up elsewhere when Optional values start brushing up against that top level of user-visible stuff. Maybe we (I) just need to get better at thinking about missing data conditions at the product design stage, or more robust defaults.
- jchb 8y ago> when Optional values start brushing up against that top level of user-visible stuff Perhaps you are under-using sum types - or enums with associated values as they are called in Swift. Difficult to get into details in this format, but for example, instead of: `enum State { case connected(Connection, SomeOtherStateRelatedToConnected) case disconnected } let state: State ` You have: ` var connection: Connection? var someOtherState: SomeOtherStateRelatedToConnected? `
- gurkendoktor 8y ago> Optional shouldn't be used for most variables and parameters. I'd agree if Swift was a general-purpose C++ replacement, but most developers use Swift to write Cocoa apps. viewController.navigationController is optional, view.superview is optional, label.text is optional; all of Apple's frameworks are built on mutable state where almost everything can be or become nil. (We can make sure that most variables and parameters aren't optional, but that only pushes the problem to other lines of code.) If we know that we've loaded a view controller from a storyboard, is `self.storyboard!.foo` really a code smell? What else should we do? The type system doesn't let us express what we know/assume about the situation, unless we completely sidestep Apple's controller infrastructure and write our own thing. > Also, take into account that in Objective-C you can send any message to a nil pointer, and the result will be nil or 0 (for scalar types), as defined by the language standard. Right, I am not saying that Objective-C handled this any better. But it boggles my mind that we have Swift's complicated type system now, and use it to rebuild an implicit source of errors from Objective-C.
- Someone 8y ago”the macOS Dock was rewritten in Swift in macOS 10.12, and Mission Control was super buggy for me in that version. I'm not blaming this on Swift” Foo was rewritten in Swift, and bar was super buggy. Why would you blame that on Swift?
- gurkendoktor 8y agoMission Control is part of Dock.app. Turns out one of these bugs even has its own blog post: https://medium.com/@julioromano/working-around-an-infamous-macos-sierra-dock-bug-a957fe8a806f https://medium.com/@julioromano/working-around-an-infamous-m...
- dep_b 8y agoTrue, I think Crashlytics still doesn't work very well for logging unusual but not crashing program situations. I would like to have an elegant solution for that. I always throw assertionErrors in case something weird happens handling an optional. However if you adopt different patterns with Swift you can exclude a lot of optionals, for example if you give every View a State enum with associated values you can avoid quite a lot of optionals: class PersonView: UIView { enum State { case empty case loading(personId: String) case loaded(person: Person) } var state: State = .empty { didSet { switch state { /* handle all different states */ } } } } Every time you switch state you need to give the right associated value and every time you are in this state this value is guaranteed to be there where before you would have an optional personId and an optional person. And it's applicable almost everywhere. I barely use optionals anymore unless I really can't replace them with an emum.
- Unknoob 8y ago> I think Crashlytics still doesn't work very well for logging unusual but not crashing program situations. Have you tried Crashlytics.sharedInstance().recordError(error) I use it to log errors on API calls in my projects. It comes in handy when I'm using third-party services and they decide to break something on their end.
- bunnycorn 8y ago> In fact, I would argue that this new trend of defensive programming in Swift Swift is not defensive, Swift can be defensive, but it can not if you don't want to. It's much more "offensive" than Objective-C, for example. Just a "!" and it's the same as Null Pointer Exception == Fatal Error.