Swift and Objective-C Interaction
In this post I am going to write how you can use Swift code in Objective-C and vice versa. I have run into this problem multiple times and every time I hit the wall. More importantly this post acts as a self reference to myself so that I can save some time for myself without searching it all over on StackOverflow.
- Using Objective-C code in Swift
Firs thing first, we will see how you can write Objective-C code and use it in the Swift. First off, create a sample project in Swift. Xcode will generate few files in Swift, but don't worry - We can still create Objective-C files manually and use it in Swift
Next, add a new Objective-C file and name it as ObjectiveCSampleFile
. During creation, Xcode will ask if you need to create bridging header or not. Select an option Create Bridging Header
and proceed
To quote Apple,
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.
In case your project has Swift and Objective-C files, but it does not have bridging header, worry not. You can go through this answer on StackOverflow which has step by step explanation on how to manually add bridging header in the project
Next step is to add a sample code in ObjectiveCSampleFile
header and implementation file as follows
// Header file
@interface ObjectiveCSampleFile : NSObject
- (void)doIt;
@end
// Implementation file
#import "ObjectiveCSampleFile.h"
@implementation ObjectiveCSampleFile
- (void)doIt {
NSLog(@"Doing It!!!");
}
@end
Now go to LanguageInterOperability-Bridging-Header.h
and import your Objective-C file in the bridging header. The code will look like this,
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "ObjectiveCSampleFile.h"
Now any Swift file in your project is ready to use Objective-C code. Say I want to use doIt
method in foo.swift
file so I can type like this,
let sampleCode = ObjectiveCSampleFile()
sampleCode.doIt()
Remember, there is no need to import Bridging header file. As long as your Swift file and bridging header remain under same module, you are good to do.
-
Using Swift code in Objective-C
Swift code can be used in the Objective-C class using file named
$(SWIFT_MODULE_NAME)-Swift.h
. For example in our current project file will be named asLanguageInterOperability-Swift.h
. Any Swift method you will write will be directly imported into this header file in the form of Objective-C source code and will be subsequently used to use Swift code
If you want to verify the existence of this $(SWIFT_MODULE_NAME)-Swift.h
in your project, go to Build Settings and search for -swift
. If this file exists, you will see result result similar to following,
If you don't already have this Objective-C generated interface header file, worry not. You can manually create a
this file in the form ofmodule_name-Swift.h
. (If your project contains spaces, replace them with underscores while naming interface header file e.g. Awesome Pro becomes Awesome_Pro-Swift.h). Once file is create, add its path under Objective-C interface header file path in Build Settings as follows
Once the interface header file for Objective-C code is ready, you are ready to use Swift code in Objective-C code.
// Import the generated header file
#import "LanguageInterOperability-Swift.h"
// Use the Swift code
ViewController* vc = [[ViewController alloc] init];
[vc swiftMethod];
That's it, and now you know how interoperate these two amazing languages in the same project. Some caveats though while importing Swift code in Objective-C
-
To use Swift code in Objective-C, classes must be annotated with
@objc
or should inherit fromNSObject
(e.g.@objc public class HelloWorld: NSObject
) -
You cannot use auto generated Objective-C header file in header file of Objective-C code. The compiler will complain that header file does not exist in the project
-
There are certain things that cannot be transformed from Swift to Objective-C. Such as generics, swift specific classes and methods, optional primitive types (
var val: Int?
) andstructs
etc. Make sure you code handles these exceptions while trying to make Swift code available on Objective-C platform
If you want to save some time exploring now it all works and want to directly play with the code, I have added the example code on the Github repository. The demo shows how to call Swift method from Objective-C and vice versa
Thank you for going through this post. If you have further questions about interoperability between Swift and Objective-C code, please let me know. I will keep updating this post as I find any other gotchas while dealing with interoperability
References:
Bridging headers creation
Mix and Match Cocoa apps
How to import Swift code to Objective-C