Swift and Objective-C, a Happy Couple

October 19, 2014

One of the great features of using Apple’s new programming language Swift, is that it and Objective-C are pretty much interoperable. I have done several iOS applications as an independant developer and they require a small amount of maintenance from time to time. Now, I was interested using Swift in my application, but I did not want to rewrite it from scratch. So what I started doing, was slowly porting parts of the application that I touched, from Objective-C to Swift. Also I made sure that any new class that I introduced to the application would be written in Swift.

This approach allowed me to chip away slowly at the problem of converting the entire application over to Swift but also allowed me to do my maintenance work and any new feature development. This article will demonstrate the very simple manner in which a Swift class can be called from Objective-C.

I started with an Objective-C project (which can be found here https://github.com/codingricky/interop-demo). It is a Single View Application, and I will introduce a Swift class that will be invoked from an Objective-C Controller.

This is my Swift Message class. It’s intentionally simple. It returns a String that will be displayed on screen.

class Message {
    func message() -> String {
        return "Hello"
    }
}

To allow for Objective-C to invoke this Swift class, there are a couple of modifications that are required.

Firstly, let’s add the @objc annotation to the class to allow for the class to be made available to Objective-C.

@objc class Message {
    func message() -> String {
        return "Hello"
    }
}

Next, we need to add in a class function so Objective-C can create new instances of this class.

So this is what our class looks like now.

@objc class Message {
    
    class func newInstance() -> Message {
        return Message()
    }
    
    func message() -> String {
        return "Hello"
    }
}

Shifting our attention back to Objective-C, for any class that will interact with Swift, we need to import a special header file that is generated by Xcode. This is in the format of ProductName/ProductModuleName-Swift.h which will make visible any of the classes/methods from Swift to Objective-C that have the correct annotations and/or modifiers.

So in my case, the import statement looks like the following:

import "Interop_Demo-Swift.h"

In my ViewController, we can use the Swift Message class, we defined earlier.

- (void)viewDidLoad {
    [super viewDidLoad];
    Message *message = [Message newInstance];
    NSString *messageString = [message message];

    UILabel *headingLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 240, 300, 30)];
    headingLabel.text = messageString;
    [self.view addSubview:headingLabel];
}

The application running in the simulator ends up looking like this.

Simple as that really. I hope this article showed you how easy it was to go between Swift and Objective-C, and potentially a way to migrate, piecemeal your application over from Objective-C to Swift.

####References####