Swift’s compatibility with Objective-C allows you to use both languages in the same project. You can use this feature, called Mix and Match, to develop mixed-language-based applications, and you can use Swfit’s latest features to implement some of the functionality of your application and seamlessly incorporate it into your existing Objective-C code.
Overview of Mix and Match
Objective-c and Swift files can coexist in a project, whether the project is originally objective-C based or Swift based. You can simply add a source file in another language to an existing project. This natural workflow makes it as easy to create an application or framework target in a mixed language as it would be in a single language.
Mixed languages have a slightly different workflow, depending on whether you’re writing an application or a framework. The following describes the common case of importing a model in a target in both languages, with more details in subsequent sections.
Import in the target of the same application
If you’re writing a mixed-language app, you may need to access objective-C code using Swift code, or vice versa. The following flow describes the application in a non-framework target.
Import Objective-C into Swift
When importing objective-C files in an application’s target for use by Swift code, you need to rely on the Bridging headers with Objective-C to expose them to Swift. Xcode automatically creates these headers when you add Swift files to an existing Objective-C application (or vice versa).
If you agree, Xcode will generate the Header file at the same time the source file is created and name it -bridge-header. h with the module name for Product. Naming Your Product Module for product.
You should edit this header file to expose objective-C code to Swift.
As a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my iOS development public number: Programming Daxin, whether you are small white or big ox are welcome to enter. Let us progress together and develop together! (The group will provide some free study books collected by the group owner and hundreds of interview questions and answers documents for free!)
Import Objective-C code into Swift at the same target
- In the Objective-C bridge file, import any headers you want to expose to Swift, for example:
1. // OBJECTIVE-C
3. #import "XYZCustomCell.h"
4. #import "XYZCustomView.h"
5. #import "XYZCustomViewController.h"
Copy the code
- Make sure that the Build setting of the Objective-C bridge file in Build Settings is based on the Swfit compiler, i.e. the path that Code Generation contains the header file. This path must be the path of the header itself, not the directory in which it resides.
The path should be relative to your project, similar to the path specified by info.plist in Build Settings. In most cases, you don’t need to change this setting.
All public Objective-C headers listed in this bridge file are visible to Swift. All Swift files for the current target can then use the methods in these header files without any import statements. Use this Objective-C code in Swift syntax just as you would use the system’s native Swift classes.
1. // SWIFT
3. let myCell = XYZCustomCell()
4. myCell.subtitle = "A custom cell"
Copy the code
Import Swift into Objective-C
When you import Swift code into Objective-C, you rely on the headers generated by Xcode to expose the Swift code to Objective-C. This is an automatically generated Objective-C header that contains all the interfaces defined in Swift code in your target. You can think of this Objective-C header as the umbrella header of Swift code. It is named after the product module name plus -swift.h. Naming Your Product Module for product.
You don’t need to do anything to generate this header file, just import it into your Objective-C code to use it. Note that the Swift interface in this header contains all the Objective-C types it uses. If you use your own Objective-C type in Swift code, be sure to import the corresponding Objective-C header into your Swift code first, The Swift automatically generated header file is then imported into the Objective-c.m source file to access the Swift code.
Import Swift code into Objective-C at the same target
In the objective-c. m source file of the same target, import the Swift code with the following syntax:
1. // OBJECTIVE-C
2. #import "ProductModuleName-Swift.h"
Copy the code
Any Swift files in target will be visible to the Objective-c. m source file, including the import statement. For information about Using Swift code in Objective-C code, see Using Swift from Objective-C.
Imported into the Swift, | Imported into the Swift, | |
---|---|---|
Swift code | Import statements are not required | #import |
Objective – C code | Import statements are not required; Objective-c ‘umbrella header is required | #import “Header.h” |
Import in the target of the same Framework
If you’re writing a mixed-language framework, you might access objective-C code from Swift code, or vice versa.
Import Objective-C into Swift
To import objective-C files into the Swift code of the same framework target, you need to import these files into the Objective-C umbrella header for the framework to use.
Import Objective-C code into Swift in the same framework
Ensure that the framework target Build Settings > Packaging > Defines Module is set to Yes. Then import the Objective-C header file you want to expose to Swift access in your umbrella header file, for example:
1. // OBJECTIVE-C
2. #import <XYZ/XYZCustomCell.h>
3. #import <XYZ/XYZCustomView.h>
4. #import <XYZ/XYZCustomViewController.h>
Copy the code
Swift will see all the header files that you exposed publicly in umbrella headers, and all Swift files in the framework target will have access to the contents of your Objective-C files without any import statements.
1. // SWIFT
2. let myCell = XYZCustomCell()
3. myCell.subtitle = "A custom cell"
Copy the code
Import Swift into Objective-C
To import some Swift files into objective-C code for the target of the same framework, you don’t need to import anything into an umbrella header file, Instead, import the headers Xcode automatically generates for your Swift code into your obj.m source file to access Swift code in Objective-C code.
Import Swift code into Objective-C in the same framework
Ensure that the framework target Build Settings > Packaging Defines Module Yes. Use the following syntax to import the Swift code into the objective-c. m source file under the same framework target.
1. // OBJECTIVE-C
2. #import <ProductName/ProductModuleName-Swift.h>
Copy the code
The Swift files contained in this import statement can be accessed by objective-c. m source files under the same framework target. For information about Using Swift code in Objective-C code, see Using Swift from Objective-C.
Imported into the Swift, | Imported into the Swift, | |
---|---|---|
Swift code | Import statements are not required | #import |
Objective – C code | Import statements are not required; Objective-c ‘umbrella header is required | #import “Header.h” |
Importing external Framework
You can import external frameworks, whether it’s pure Objective-C, pure Swift, or mixed languages. The process for importing an external framework is the same regardless of whether the framework is written in one language or contains two languages. When importing external frameworks, make sure Build Setting > Pakaging > Defines Module is set to Yes.
Import frameworks into Swift files for different targets using the following syntax:
1. // SWIFT
2. import FrameworkName
Copy the code
Import frameworks into objective-c. m files for different targets using the following syntax:
1. // OBJECTIVE-C
2. @import FrameworkName;
Copy the code
Imported into the Swift, | Imported into the Objective – C | |
---|---|---|
Arbitrary language framework | import FrameworkName | @import FrameworkName; |
Use Swift in Objective-C
After you import the Swift code into an Objective-C file, use the Swift class with normal Objective-C syntax.
1. // OBJECTIVE-C
3. MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
4. [swiftObject swiftMethod];
Copy the code
Swift classes or protocols must be marked with @Objective-C attributes to be accessible in Objective-C. This attribute tells the compiler that the Swift code is accessible from objective-C code. If your Swift class is a subclass of objective-C, the compiler will automatically add @Objective-C attribute for you. See Swift Type Compatibility.
You can access the Swift class or protocol and tag something with an @Objective-C attribute, as long as it’s objective-C compatible. Not including the following features unique to Swift:
- Generics – paradigm
- Tuples – Tuples
- Enumerations defined in Swift – Enumeration defined in Swift
- Structures defined in Swift – A structure defined in Swift
- Top-level functions defined in Swift – Swift Indicates the top-level functions defined in Swift
- Global variables defined in Swift – Global variables defined in Swift
- Typealiases defined in Swift – Typealiases defined in Swift
- Swift-style variadics – Swift style variable parameters
- Nested types – Nested types
- Curried functions – Currized functions
Methods that take generic types as arguments, or return tuples, for example, cannot be used in Objective-C.
To avoid circular references, do not import Swift code into objective-C headers. However, you can use it by forward declaring a Swift class in objective-C headers. Note, however, that you cannot inherit a Swift class in Objective-C.
Reference the Swift class in an Objective-C header
Declare the Swift class forward like this:
1. // OBJECTIVE-C
2. // MyObjective-CClass.h
4. @class MySwiftClass;
6. @interface MyObjective-CClass : NSObject
7. - (MySwiftClass *)returnSwiftObject;
8. /* ... */
9. @end
Copy the code
Product module naming
The names of the header files that Xcode generates for the Swift code, and the objective-C bridge files that Xcode creates, are both generated from the name of your Product module. By default your product module name is the same as the product name. However, if your product name has special characters (nonalphanumeric, non-numeric, alphanumeric characters), such as periods, they will be replaced by underscores (_) as your product module name. If the product name starts with a number, the first number is replaced with an underscore.
You can give the product module name a custom name that Xcode will use to name the bridged and automatically generated header files. You only need to modify the Product Module Name in build Setting.
Problem solving Tips
- Think of Swift and Objective-C files as the same set of code, and note naming conflicts;
- If you use frames, make sure Build Setting > Pakaging > Defines Module is set to Yes.
- If you are using objective-C bridge files, make sure that the Build setting of the Objective-C bridge file in the Build Settings is based on the Swfit compiler, i.e. the path that Code Generation contains the header file. This path must be the path of the header itself, not the directory in which it resides;
- Xcode uses the name of your Product module, not the target name, to name objective-C bridge files and automatically generated headers for Swift. Naming Your Product Module;
- In order to be available in Objective-C, the Swift class must be a subclass of the Objective-C class, or marked with @objective-C;
- When you import Swift into Objective-C, remember that Objective-C does not translate swift-specific features into Objective-C counterparts. Using Swift from Objective-C;
- If you use your own Objective-C type in Swift code, be sure to import the corresponding Objective-C header into your Swift code first, The Swift auto-generated header file is then imported into the Objective-c.m source file to access the Swift code.