My current plans for Swift adoption in 2015:
- I’m just finished a contract project in Swift 1.2. It was a really great experience for working through Swift and finding it’s strengths and weaknesses.
- At work, we may introduce some Swift 2.0 into our application for new source, but there is currently no pressing need to transition anything existing.
- Our library we ship to other developers will continue shipping in Obj-C. There are currently no plans to port to Swift as Swift 2.0 still doesn’t meet our requirements, and a full port would be technically impossible. But we’ll be cleaning up the interface for bridging well to Swift, and hopefully beginning to distribute as a framework in our next major version.
There are reasons for these different approaches, and some things I’d still love to see from Swift to be more comfortable with it:
C++ Support
Swift still cannot directly link to C++ code. The current workaround for this is to wrap C++ code in Obj-C code. The two schools of thought on this are that Swift will never get C++ support, or C++ support may come to Swift in a future enhancement. This is a big reason a full port of our library for third party developers will not get a Swift version in it’s current form: It contains shared cross platform C++ code. If Swift does not get C++ support, than Obj-C will be used in the project indefinitely. And we’re not alone: Most major companies are in this position as well. Microsoft, Adobe and Apple are just a few companies that have large C++ code bases for cross platform projects, and it’s unlikely they’d be able to drop Obj-C as well. It’s possible to add another layer of abstraction in Swift around our Obj-C code, but that doesn’t seem like an efficient use of resources, especially when Obj-C bridging is making such large strides.
Dynamic Swift
Swift is still a mixed bag when it comes to using some of the more dynamic concepts from Obj-C. KVO can still be painful, especially when trying to mix in Swift concepts. For example, it’s not possible to declare a Swift dynamic function that is also an emum. Having to declare functions dynamic at all is also a painful design decision. It seems that it would be possible for Apple to split the difference. They could allow functions to be accessed both statically and dynamically automatically. Directly calling a function could follow the fast, static path, while dynamic observation and calls could be done through a lookup table that simply forwards to the static function. My understanding is that dynamic functions are all or nothing currently, but having a middle ground where functionality like method swizzling is just not support, or not supported well would be a good compromise.
Like C++ support, there are two different thoughts on this. One is that Swift should be totally a static language and that Apple platforms should make a huge shift away from dynamic types of programming. The other is that Swift can find some sort of middle ground, which I really hope is the course Apple takes. Swift really shines in a lot of situations that pair well with type safety, but it can really be painful to use in dynamic programming where Obj-C excels. Obj-C was born out of painful experiences with languages that were too static, and it would be a shame to backtrack on that.
Language Stability
Swift is still an unstable language, which can cause deeper problems beyond just issues with maintaining source. The Swift 2.0 ABI is still considered unstable by Apple (which I re-confirmed post WWDC), so shipping a precompiled library/framework is still not a advisable option (this is the other significant issue with shipping our library with any Swift.) An unstable ABI means that a Swift project can only link to other pre-compiled Swift code that was compiled with the same version of Xcode. This makes it difficult to service multiple customers with the latest fixes at the same time.
The unstable nature of the language itself is a smaller problem, but can still be an obstacle. If we have multiple active branches, changes in Swift can causes schisms in our repository. It also makes recompiling and resigning an older application much more difficult. We’d feel a lot more secure in our Swift investments if the language was more stable. iOS has small API changes from release to release, but Obj-C has been extremely stable.
Cocoa Support
Swift is still unwieldy under Cocoa, but Swift 2.0 and the latest release of Obj-C has made huge strides and I’m really looking forward to it. I think this will continue to improve, but parts of Cocoa that use pointers are still painful, and types like NSNumber don’t bridge to native Swift types. The one really bright spot is Swift 2.0’s formalized error handling is a great advance, and works extremely well with Cocoa. I’d like to see the dynamic support in Swift brought up to speed to better bridge with Cocoa APIs and KVO. I’d even be ok with a KVO replacement in Swift as long as it could bridge. Observing class properties is a big part of Cocoa, and I’d like it to be a big part of Swift as well. The exceptions enhancements are welcome as well. I was happy that Swift had eliminated exceptions, but I quickly ran into problems porting existing unit testing code that tested a Cocoa style API.