How to use Swift classes in Objective-C

How to use Swift classes in Objective-C



It is possible to use Swift classes from Objective-C code (and vice versa) – but Apple’s documentation is a little cloudy (and verbose) on how to actually achieve this magic.

Here’s how it works.

I’m assuming we have a project written in Objective-C, but there’s a new Swift class that needs to be used and we want to access it from Objective-C code, with Objective-C syntax.

Preparing your Xcode Project

As soon as we add a Swift class to an Objective-C project, we’ll get an invitation from Xcode: “Shall I create a Bridging Header” it asks. Technically we don’t need this: it will be useful to do the reverse of what we want to do, i.e. make Objective-C code usable in Swift.

Agree to the friendly offer anyway, so both classes can access each other natively. It may come in handy for future use.

Screen Shot 2015-11-13 at 18.09.59

You’d think this is all the information our clever Xcode should need, but it isn’t. We’ll also need to tell it that we want to use both Swift and Objective-C in the same project (as if that wasn’t obvious).

To do this, head over to your target and find the Build Settings tab. We’re looking for an option called Embedded Content contains Swift Code (under Build Options):

Screen Shot 2015-11-13 at 18.50.20

That’s all we have to do in Xcode for now.

Preparing the Swift Class

Let’s assume our Swift class is a UIViewController. It may look like this (I’ll leave out all the properties and methods this class may have):

class SwiftViewController: UIViewController {
// ... 

To make this class accessible from Objective-C, we need to add the @objc keyword just before the class declaration. This tells the compiler to do some magic behind the scenes (namely, create an invisible header file – more on that in a moment):

@objc class SwiftViewController: UIViewController {
// ... 

That’s all we need to do here.

Preparing your Objective-C Class

Finally, we need to import a magically generated Swift Header into our Objective-C class, just like we would when we want to instantiate any other class. Thing is, Swift doesn’t have header files – so what’s going on?

Well, the header we need to import doesn’t actually exist – not as a physical file. It’s something that Xcode generates on the fly, behind the scenes. Its name is auto-generated from your project title, but the file doesn’t auto-complete when you try to @import it (because that would be way too easy).

So the way to find out WHAT this file is called is by cruising over to our target again, and search for Swift under Build Settings. Find a section called Swift Compiler – Code Generation, and an option called Objective-C Generated Interface Header Name:

Screen Shot 2015-11-13 at 18.58.54

My project’s name is “Mix and Match” (notice that two spaces in that title), so Xcode generated a file called “Mix_and_Match-Swift.h“. That’s what we need to import into our class.

DO NOT import the Bridging Header file that Xcode generated earlier called “Mix and Match-Bridging-Header.h”, even though that one auto-completes just fine.

#import "ViewController.h"
#import "Mix_and_Match-Swift.h"

@interface ViewController ()


Note that we only ever need one magic header files, no matter how many Swift classes are in our project: every Swift class that has the @objc in front of it will be included via this thing. It is truly magical.

Calling Swift Methods from Objective-C

With all this prep-work out of the way, let’s call the following hypothetical Swift method in our Objective-C class:

    func test () -> String {
        return "Swift says hi!"

As we normally would, we’ll alloc and init the class to create an instance (or grab a reference to it), then call the method:

SwiftViewController *controller = [[SwiftViewController alloc]init];
NSString *string = [controller test];
NSLog(@"%@", test);

// Output: Swift says hi!

Tip: If you try this just after adding new code to the Swift class, code completion won’t work. It’s not you, it’s a “feature”. Hit CMD-+B to build the project: this will force the compiler to have a closer look at all classes involved. Now code completion should work just fine. You have to do this every time you change code in Swift, at least in Xcode 7.1.1.


This concept of importing Swift classes and using them from Objective-C works well for all methods, properties and protocols.

For all intents and purposes, Xcode will make our Swift class available to us as if it was a native Objective-C class.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s