On Migrating to Swift 3 and Swift 2.4
Over the past couple of weeks, new versions of macOS, iOS, tvOS, and watchOS have been released. Along with them came a new Xcode and a new version of Swift.
When you open a project in the new Xcode, it immediately offers to convert the project to the new Swift version—either to version 2.3, which is almost unchanged as an intermediate version, or straight to the new Swift 3, which has quite a lot of changes.
Converting the project itself is not difficult, because Xcode has a built-in converter. I decided to try 2.3 first so as not to dive into the weeds of the changes. The working project converted without problems, and then dependency hell began. I use Carthage; all dependencies are compiled into a .framework that you import into your project. Once imported, you usually do not need to touch the project itself anymore, just rebuild the dependencies. In the first week after the release, many developers quickly shipped updates—a release for Swift 2.3 and a release for Swift 3. But not everyone. For example, SwiftyJSON: its developers disappeared for a while, and the framework is very popular. I had to dig around—the dependencies that had not been updated were fortunately picked up by third-party developers. They forked them, moved everything to Swift 2.3, and sent pull requests to the original repositories.
I had to spend some time replacing some dependencies with forks. And hooray, the project finally built. During the following week, the authors of all the dependencies I use had already shipped Swift 2.3 releases. With a clear conscience, I switched the dependencies back to the originals.
Naturally, it made sense to move to Swift 3 as soon as possible, because 2.3 is a temporary version and support for it will disappear in future Xcode releases. Besides, Swift 3 was promised to be, if possible, the last version that would break compatibility with previous versions.
Again, the project itself converted to Swift 3 without major issues. Not everything, but a lot. And whatever did not convert automatically, Xcode itself suggested fixes during compilation; for the most part I only had to click the mouse and let it apply them. Even though I waited until all dependencies were updated to Swift 3, I still had to sweat a bit. Incidentally, if a framework is compiled in Swift 2.3, you cannot include it in a Swift 3 project. And vice versa too. I cleared up various problems—and then a different kind of headache started. AlamoFire for Swift 3 did not just get updated, it got a major update—with renamed classes and API changes. As a result, I had to rewrite some methods by two thirds. Although in most cases I just had to swap argument order and rename things here and there. Plus, now to pass GET parameters, you have to add them to the URL string by hand; previously the parameters argument could do that, but now that data is sent in the request body as if we had filled in a form.
But in the end everything turned out fine, although the migration took time and effort. Onward, into the future.
P.S. The open-source version of Swift 3, which can run on Linux, still does not have a full implementation of the classes for working with networking. And the backend framework Perfect does not compile on Ubuntu 16.04. So Swift for the backend is postponed again for now.