Swift
Objective-C
Interoperability
iOS Development
Programming

How do I call Objective-C code from Swift?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction to Mixing Swift and Objective-C

Swift, introduced by Apple in 2014, was designed to coexist seamlessly with Objective-C, allowing developers to utilize existing codebases and libraries. This interoperation is fundamental for maintaining and expanding older iOS and macOS projects, ensuring that you can leverage existing components while incorporating Swift's modern syntax and features.

Prerequisites

Before we delve into the details of calling Objective-C code from Swift, ensure you have:

  1. A mixed-language project set up, with both Swift and Objective-C files.
  2. Objective-C files with .m and Swift files with .swift extensions.
  3. Bridging Header configured correctly for seamless integration.

Bridging Header

The bridging header is crucial for calling Objective-C code from Swift. It's essentially a header file within your project that exposes Objective-C classes to Swift files.

Setting Up a Bridging Header

  1. Create a Bridging Header: If Xcode prompts you to create a bridging header when adding an Objective-C file to a Swift project, accept the offer. If not:
    • Create a new header file and name it something like ProjectName-Bridging-Header.h.
    • In your bridging header, import the Objective-C headers you want to expose to Swift.
objective-c
   // ProjectName-Bridging-Header.h
   #import "SomeObjectiveCFile.h"
  1. Configure the Bridging Header Path:
    • Go to your project settings.
    • Navigate to Build Settings.
    • Find the Objective-C Bridging Header setting and input the relative path to your bridging header file, such as ProjectName/ProjectName-Bridging-Header.h.

Accessing Objective-C Code in Swift

With the bridging header configured, Swift can utilize the Objective-C classes and methods as if they were native Swift code.

Example: Calling an Objective-C class in Swift

Suppose you have an Objective-C class Greeter:

Objective-C Implementation (Greeter.m):

objective-c
1#import "Greeter.h"
2
3@implementation Greeter
4
5- (NSString *)greetingWithName:(NSString *)name {
6    return [NSString stringWithFormat:@"Hello, %@!", name];
7}
8
9@end

Objective-C Header (Greeter.h):

objective-c
1#import <Foundation/Foundation.h>
2
3@interface Greeter : NSObject
4
5- (NSString *)greetingWithName:(NSString *)name;
6
7@end

Using the Greeter class in Swift:

swift
1// Swift file
2let greeter = Greeter()
3let greeting = greeter.greeting(withName: "World")
4print(greeting)  // Prints "Hello, World!"

Data Type Compatibility

Swift and Objective-C interoperable projects require a correct understanding of type compatibility.

  • Classes/AnyObject: Swift classes and Objective-C classes (NSObject) are interoperable.
  • Primitives: Swift's Int and Bool map to Objective-C's NSInteger and BOOL.
  • Collections: Swift's Array and Dictionary are bridged to NSArray and NSDictionary, respectively.

Here's a table summarizing some key type mappings:

Swift TypeObjective-C Type
IntNSInteger
BoolBOOL
StringNSString
ArrayNSArray
DictionaryNSDictionary
Optionalnullable/ null-resettable
AnyObjectid

Handling Nullability

In Swift, optionals (e.g., String?) signify the potential absence of a value, which aligns with Objective-C's convention of using nil. However, you must explicitly declare nullability in Objective-C headers to avoid miscommunications.

  • Non-null (nonnull): Maps to non-optional types in Swift.
  • Nullable (nullable): Maps to optional types in Swift.
objective-c
1@interface Example : NSObject
2
3- (nonnull NSString *)nonNullableMethod;
4- (nullable NSString *)nullableMethod;
5
6@end

Objective-C to Swift Conversions

To utilize Swift from Objective-C codebases, doors open through an @objc attribute. This attribute exposes Swift functions and classes to Objective-C.

Exposing Swift to Objective-C

swift
1@objc class SampleClass: NSObject {
2    @objc func sampleMethod() -> String {
3        return "Hello from Swift"
4    }
5}

You would then use this Swift class in Objective-C as follows:

objective-c
SampleClass *sampleInstance = [[SampleClass alloc] init];
NSString *result = [sampleInstance sampleMethod];
NSLog(@"%@", result);

Conclusion

Calling Objective-C code from Swift enriches your development process, fostering code reuse, and adding flexibility. While configuring a bridging header and understanding type compatibility is essential, mastering these concepts allows you to transition smoothly between Swift and Objective-C, ensuring robust implementation for your applications.

Using these practices, you can evolve your apps by utilizing existing Objective-C libraries while embracing Swift's modern programming paradigms.


Course illustration
Course illustration

All Rights Reserved.