Guides and Sample Code


Using Swift with Cocoa and Objective-C (Swift 4.1)

On This Page

Migrating Your Objective-C Code to Swift

Migration provides an opportunity to revisit an existing Objective-C app and improve its architecture, logic, and performance by replacing pieces of it in Swift. For a straightforward, incremental migration of an app, you’ll be using the tools learned earlier—mix and match plus interoperability. Mix-and-match functionality makes it easy to choose which features and functionality to implement in Swift, and which to leave in Objective-C. Interoperability makes it possible to integrate those features back into Objective-C code with no hassle. Use these tools to explore Swift’s extensive functionality and integrate it back into your existing Objective-C app without having to rewrite the entire app in Swift at once.

Preparing Your Objective-C Code for Migration

Before you begin migrating your codebase, make sure that your Objective-C and Swift code has optimal compatibility. This means tidying up and modernizing your existing Objective-C codebase. Your existing code should follow modern coding practices to make it easier to interact with Swift seamlessly. For a short list of practices to adopt before moving forward, see Adopting Modern Objective-C.

The Migration Process

The most effective approach for migrating code to Swift is on a per-file basis—that is, one class at a time. Because you can’t subclass Swift classes in Objective-C, it’s best to choose a class in your app that doesn’t have any subclasses. You’ll replace the .m and .h files for that class with a single .swift file. Everything from your implementation and interface goes directly into this single Swift file. You won’t create a header file; Xcode generates a header automatically in case you need to reference it.

Before You Start

  • Create a Swift class for your corresponding Objective-C .m and .h files by choosing File > New > File > (iOS, watchOS, tvOS, or macOS) > Source > Swift File. You can use the same or a different name than your Objective-C class. Class prefixes are optional in Swift.

  • Import relevant system frameworks.

  • Fill out an Objective-C bridging header if you need to access Objective-C code from the same app target in your Swift file. For instructions, see Importing Code from Within the Same App Target.

  • To make your Swift class accessible and usable back in Objective-C, make it a descendant of an Objective-C class. To specify a particular name for the class to use in Objective-C, mark it with @objc(name), where name is the name that your Objective-C code uses to reference the Swift class. For more information on @objc, see Swift Type Compatibility.

As You Work

  • You can set up your Swift class to integrate Objective-C behavior by subclassing Objective-C classes, adopting Objective-C protocols, and more. For more information, see Writing Swift Classes and Protocols with Objective-C Behavior.

  • As you work with Objective-C APIs, you’ll need to know how Swift translates certain Objective-C language features. For more information, see Interacting with Objective-C APIs.

  • When writing Swift code that incorporates Cocoa frameworks, remember that certain types are bridged, which means you can work with Swift types in place of Objective-C types. For more information, see Working with Cocoa Frameworks.

  • As you incorporate Cocoa patterns into your Swift class, see Adopting Cocoa Design Patterns for information on translating common design patterns.

  • For considerations on translating your properties from Objective-C to Swift, read Properties in The Swift Programming Language (Swift 4.1).

  • Use the @objc(name) attribute to provide Objective-C names for properties and methods when necessary. For example, you can mark a property called enabled to have a getter named isEnabled in Objective-C like this:

    1. @objc var enabled: Bool {
    2. @objc(isEnabled) get {
    3. // ...
    4. }
    5. }
  • Denote instance (-) and class (+) methods with func and class func, respectively.

  • Declare simple macros as global constants, and translate complex macros into functions.

After You Finish

  • Update import statements in your Objective-C code (to #import "ProductModuleName-Swift.h"), as described in Importing Code from Within the Same App Target.

  • Remove the original Objective-C .m file from the target by deselecting the target membership checkbox. Don’t delete the .m and .h files immediately; use them to troubleshoot.

  • Update your code to use the Swift class name instead of the Objective-C name if you gave the Swift class a different name.

Troubleshooting Tips and Reminders

Even though each migration experience is different depending on your existing codebase, there are some general steps and tools to help you troubleshoot your code migration:

  • Remember that you cannot subclass a Swift class in Objective-C. Therefore, the class you migrate cannot have any Objective-C subclasses in your app.

  • Once you migrate a class to Swift, you must remove the corresponding .m file from the target before building to avoid a duplicate symbol error.

  • To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class.

  • When you bring Swift code into Objective-C, remember that Objective-C won’t be able to translate certain features that are specific to Swift. For a list, see Using Swift from Objective-C.

  • Command-click a Swift class name to see its generated header.

  • Option-click a symbol to see implicit information about it, like its type, attributes, and documentation comments.