You’ve probably had it happen to you. You find a project on GitHub in Swift 3 you want to look at or update. You might have an old project Apple is urging you to update or kick out of the app store.. There were a few changes in Swift 4 and Xcode 9 that make those cases a bit of an annoying challenge. Let’s look at how to do it.
First you need an old, but not too old file. By old I mean in Swift 3. Swift 2 and older you have to convert to Swift 3 using Xcode 8 before this will work.
I’ll use an old file of mine demonstrating navigation controllers, which you can download from the GitHub repository. Open the project, and you’ll see two warnings on the project.
Click the warnings at top and you’ll see the two build time warnings.
The first is Conversion to Swift 4 is available. If you click on that one, a window appears helping you convert it.
Your target is selected and you just click Next.
The next question is the big deal.
Swift 4 removed Objective C inference for efficiency reasons. The most common use of this is instances of
UIButton made completely in code. Programmatic targets for buttons and other controls use this inference, so there can be problems, but ones you can easily fix by making all action targets
@IBActions. So go ahead and minimize inference. Hit Next
Xcode will tell you that there will be manual steps necessary. There is a migration guide you can attempt to read, but I don’t suggest it. It doesn’t tell you how to fix what’s ahead, and where to fix it. Just click OK. You’ll get a message telling you this went successfully, and it’s time to do the updating to the project. Update the project.
Once this finishes, You have one more warning.
Click on the warning and you’ll get the settings that will change:
Click Perform Changes. This will do its thing and it looks like everything is working correctly. That’s where you may get into trouble. Press Command-B to build the project. You’ll get at least one if not two errors.
These errors are build settings for the project and target relating to the @objC setting you clicked earlier. You have to manually turn them off. Click Build Settings.
In the search box put @objc.
In the setting that shows, turn that to Off or Default.
You have to do this to the target too. Open the project and targets list on the side of the settings panel. Select the target, and do this again. Check to see if this is on.
Set it to Default or Off.
If you had more targets, like watch extensions or watchApp targets for Apple watch projects, you’d have to do this step to those too. You’ll have one warning for every target.
Build again with Command-B. That should clear the warnings and you have a working project. Like most of my old projects, this project used storyboards, and no target-action controls programmatically. If you do you may have to resolve those with an explicit
@objC, but better than that use
@IBAction in front of the declaration of the action even for programmatic targets to prevent this error.
That should convert a Swift 3 project to the latest and greatest version.