Tidbit: Bridging Objective-C to Swift

Objective-C

A Brief History of Objective-C

1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix.

1980 - Alan Kay creates Smalltalk and invents the term "object oriented." When asked what that means he replies, "Smalltalk programs are just objects." When asked what objects are made of he replies, "objects." When asked again he says "look, it's all objects all the way down. Until you reach turtles."

1986 - Brad Cox and Tom Love create Objective-C, announcing "this language has all the memory safety of C combined with all the blazing speed of Smalltalk." Modern historians suspect the two were dyslexic.

(source)

Overview of Objective-C

Objective-C is a very influential object-oriented language that was made about 30 years ago, and has been the cornerstone of Apple development. Ever since NeXT, which was actually written with Objective-C, it was expected that Objective-C would be the main language used to make Mac apps (and in the future, iOS apps).

Objective-C is a compiled language which is a strict superset of C (meaning that any set of C code is considered valid, compilable Objective-C code). Objective-C adds features such as OOP, messages, categories, and protocols on top of all the nice features that is provided to you by the C language.

I'll let you make your own metaphor about shooting yourself in the foot with Objective-C. Witty suggestions may be featured in future iterations of the course.

For more information about Objective-C, you should go to the first lecture on the old iOS StuCo website, which is written, and now managed, by Tyler Hedrick. We'll port the lecture over to the new website shortly.

However, it is pretty much required that you read up on the basics of Objective-C syntax if you're planning to incorporate it into your Swift app. At the very least, you need to know how to read Objective-C code, not write it.

Putting Objective-C in a Swift App

It's very reasonable to have an application that uses both Objective-C and Swift For those of you that are using Cocoa Controls, you will likely have to do this. The good news is that Swift and Objective-C (incidentally, C, C++, and Objective-C++ also) are funneled into the same compiler that Xcode uses to compile your code, so interoperability between the two (or, five) languages is almost as simple as just including them in your project.

To specifically use Objective-C in your Swift app, you need something called a bridging header. This is basically a .h file with a special name and includes all the .h files of your Objective-C code.

Suppose you want to include Objective-C code with the following files:

If you read up on the specifics of Objective-C, you'll know that .h files define the interface of a class, and .m files define the "mmmmplementation" of the class. We only need to worry about the .h files in order to perform the bridging.

Drag your Objective-C files into your Swift project. Xcode will ask you automatically if you'd like to add a bridging header into your project. If you do so, Xcode will take care of all of it for you. But we'll tell you how to do it manually also."

You can create a bridging header yourself by choosing File > New > File > iOS > Source > Header File and call it "<Your app name>-Bridging-Header.h". Now, just put Objective-C import statements for all the class you want to include in your app. For our example, this is simply:

#import "MyClass.h"
#import "MyOtherClass.h"

And that's it! Congrats, you can use Objective-C code in your Swift app. Suppose you add a class called FTMarble defined by FTMarble.h into your Swift code, where FTMarble.h looks like:

//
//  FTMarble.h
//  FaceTilt
//
//  Created by Michael Gazzola on 4/16/14.
//  Copyright (c) 2014 Michael Gazzola. All rights reserved.
//

#import <Foundation/Foundation.h>

// The marble exists in a 2-D world, so we only need x and y acceleration.
typedef struct {
    double xAccel;
    double yAccel;
} FTMarbleAcceleration;

@interface FTMarble : NSObject

- (id)initWithSize:(CGSize)size;
- (void)updateMarbleAcceleration:(FTMarbleAcceleration)accel;
- (void)updateMarbleRotation:(double)rotation;
- (CGPoint)center;
- (CGAffineTransform)rotation;

@end

This code should look familiar to you. But, to use this code in your Swift app, you may simple say:

let myMarble: FTMarble = FTMarble(size: CGSizeZero)
let myRotation: CGAffineTransform = myMarble.rotation()
let myCenter: CGPoint = myMarble.center()
myMarble.updateMarbleRotation(42.0)
myMarble.updateMarbleAcceleration(FTMarbleAcceleration(xAccel: 42.0, yAccel: -42.0))

And yes, all the autocomplete with Xcode works perfectly fine.

Putting Swift into an Objective-C App

Why are you making an Objective-C app? Get out. Now.