The Swift 3 to 4 migration code required fewer changes and took an afternoon to complete. Swift changed the original 4.0 goal from ABI stability to source compatibility, and this code compatibility is really good, this goal is achieved. While syntactic compatibility is not everything for a mature project, this update also brings some new changes.

3.2 and 4.0

Swift also offered versions 2.3 and 3.0 in 3.0, and 3.2 in 4.0 as well. From the code in my project, there are very few changes to be made from 3.0 to 3.2, just a recompilation. The community’s response to compatibility 3.2 doesn’t suggest any major changes. So it will be a smooth transition for teams who are postponing 4.0 and can safely switch to Xcode 9.

To make the migration process smoother, the Swift framework supports versions 3.2 and 4.0 mixed. If you have several components, you can upgrade to 4.0 for a single component. Such a large team can move all the code to 4.0 at once. However, compatibility between 3.2 and 4.0 is not as good as it seems.

First, there’s cocoapods. The Pods Framework can only specify one version of Swift. Pods Automatically compiling with Swift 4.0 in Xcode 9 Beta 1. By default, POD builds all with a swift version, which needs to be specified separately for different libraries.

After encountering this problem, I migrated all the components to 4.0. Since the APP has a lot of business codes, I hope to move to 3.2 first, so that Xcode 9 can be supported as soon as possible, and my colleagues can adapt to iOS 11 as soon as possible. However…

Xcode does not disappoint me. There is no error when compiling Xcode.

Compiling as Swift 3.2, with ‘XXX’ build as Swift 4.0(this is supported but may expose additional Compiler issues)

Although we support mix, but also can mix wrong, so you still don’t mix. However, I heard that the project of Dingxiang Garden is currently the main APP 4.0, and the mixing of component 3.2 is successful. So, you know, if you want to take a chance.

By the way, the new build system for Xcode 9, which I can’t compile at all (probably because we mix OC?) “Without any error messages. Apple’s software quality is truly exceptional, programming for luck.

Community follow-up in time

So in fact, you can either stay put and stop at 3.2. Once you migrate, you need to migrate all the way to 4.0.

Fortunately, due to minor syntax changes, most of the Swift libraries I used support 4.0. The only exception is DOFavoriteButton, a “like” control. Some countries that were slow to follow up were RxGesture and EZSwiftExtensions, but they too had a branch of 4.0. Some people raised PR for 4.0. It is expected that THEY can join in a few days. Let’s just say the maintainers aren’t motivated enough. Here is the pod I used:

3.2 4.0
RxSwift/RxCocoa There is no 4.0.0 – beta. 0
SnapKit There is no 4.0.0
CryptoSwift 0.7.0 0.7.1
Alamofire 4.5.1 4.5.1 Compatibility (5.0 not released yet)
ObjectMapper 2.2.9 3.0
SwiftyAttributes 3.2.0 4.0.0
Kingfisher 4.1.0 4.0
MonkeyKing There is no 1.4.0

In general, 3.0 builds directly under 3.2, so “none” does not mean that it cannot be used. It means that the developer has not separately declared a version compatible with 3.2.

4.0 began to officially part company with OC

In order to take care of the original developers, the goal of Swift 2.0 is to be as compatible with OC as possible. Except for a few basic data types such as Int and String, other apis are consistent with OC. You can write Swift using OC’s habits. By 3.0 the Swift system began to evolve on its own, with its own naming convention.

By 4.0, Xcode has rewritten the compiler with Swift. Although the New build system is still preview and does have a lot of problems, the compilation optimization for Swift has been greatly improved. I can already sense apple wanting to ditch OC, or at least very clearly loathing it.

At the code level, all attribute methods of a class that is a subclass of NSObject are automatically added to the bridge of the OC call by default. In 4.0, this feature was disabled. This is also a relatively large amount of work for migration 4.0 (for projects co-built with OC). We used Swift to define a control that can call all properties and methods exposed by this control after importing the module header file in OC. However, after the migration to 4.0, all properties and methods are not accessible by default. You need to add @objc before the property methods to be exposed to the OC.

This change is very far-reaching. This leaves developers with a choice between the two. If we write a component in Swift that needs to support OC plus the @objc flag, compile time will generate a declaration for OC calls, which degrades performance a bit. But if it is not added, OC cannot be called. The deeper reason is that at the time of writing the component we do not know exactly whether the business side is calling with OC or Swift. Unless the business code is all Swift. Or you can just do OC Bridges all over the place, @objc everywhere, and if you’re calling Swift, you’re adding all this stuff.

Another detail emerges. If we declare a property size for UIView in OC, we declare a property size in Swift. If it is in a framework, it will fail to compile and indicate a conflict. However, if the two are written in different frameworks, Xcode will not tell you. At 8, the size call will end up in the OC method, but at 9, when the OC framework is introduced into Swift code, the code will crash and will not know which library size should be called. This is obviously a bug in the compiler, but it also reflects the increasing number of problems with OC and Swift mixing, and the increasing differences between the two systems.

The cost of migrating to 4.0 is much less than before, ABI stability is most likely coming in 5.0. This is good news for developers who are waiting to see if Swift is stable, and believe that Swift adoption will be even higher. Swift annual version of the upgrade and OC will become more and more different, bringing a lot of uncertainty to the mixed project, for the mixed project is able to migrate some code to Swift.

One of my lessons with Xcode is to share it with you again: There are two versions of Xcode, an unstable version and a more unstable version.

Follow me on social networks:

  • Twitter: @Qingchun Road Zhuofugui
  • Weibo: @Zhuo without a story