Programming Language Migration

A Step By Step Guide to Convert a Full Objective-C App to Swift

By Gurdeep Singh
March 14, 2018 2. min read
Last update on: August 25, 2020

Since its release back in 2014, Apple’s programming language Swift has undergone phenomenal growth. The programming language has managed to make its place in the chore of Top 10 Programming languages, sharing the position with its predecessor, Objective-C. But the war of swift vs objective-C never mellows down.

With this rise in popularity and exciting features, a lot of iOS application developers who were previously working with Obj-C has switched to Swift programming language. In fact, Within the fight of swift or Objective-C for iOS, Various iOS apps like LinkedIn, Yahoo Weather, Hipmunk, and Lyft have already been upgraded from Objective-C to Swift, while many are planning to convert an Objective-C app to Swift.

FACTORS MAKING SWIFT A BETTER OPTION

Personally, I have seen the evolution of Swift since its first version was unveiled and I can say that between swift vs C, Swift supersedes Objective-C based on factors, like

Open-Source

Swift is an open-source language and the swift code can be portable on many more platforms than Objective-C was ever.

Speed

Swift for iOS development is a static-typed language which works with LLVM compiler and can reuse the existing code, eradicate unused resources, manage inline functions, and so on. Besides, its working is based on one of C++ fastest algorithm calculation arithmetics which in turn proves it to have a competitive edge over its predecessor.

According to what Apple claims and I have experienced, Swift search algorithm is 2.6 times faster than Objective-C.

Readability

Unlike Objective-C, Swift is not tied to C foundations. It empowers iOS developers to remove nested method calls, skip a semicolon at the end of a line, avoid putting @ at the beginning of a keyword, concatenate string using “+” sign, and so on. Furthermore, the Swift class is not divided into parts, the interface and the implementation. This cut down the code length to nearly half, making it more readable.

For example, when Lyft app was rewritten in Swift language from scratch, the app code decreased from 75,000 to 25,000 lines. This impressive figures cut the efforts of the developers without affecting the performance of the app at the customer end.

Interactive Coding

With its Playgrounds feature, it let the programmers write a chunk of code or algorithm while gathering feedback along the development phase. As the Swift code is written using data visualizations, this makes the app development process easier and approachable.

Safety

Swift is a safer and more secure language for building an app as per the present market trends. Its syntax and language construct has excluded the types of mistakes commonly observed while coding in Objective-C language. This implies there are lesser chances of app crash and cases of problematic behaviour.

Unlike that in the case of Objective-C, code written in Swift can be compiled and the errors can be fixed, along with the code writing part. Hence, Swift act better and faster in the testing process, when compared to the process of testing the Objective-C code.

Maintenance

Since Swift has no dependency on C like its predecessor, the maintenance in case of Swift app development is far much easier. Something that made Swift to be the future of iOS app development.

In case of building an iOS app using Objective-C, developers were supposed to maintain two distinct code files to boost build time and code efficiency. However, Swift dropped this two-file mechanism, merging the Objective-C header (.h) and implementation files (.m) into a single file (.swift). The LLVM compiler automatically discovers dependencies while reading the Swift file, which is a great benefit to the iOS application developers.

Apart from the above-mentioned factors, the worth-mentioning benefit of choosing Swift over other Apple’s programming language is its compatibility with Objective-C. Apple has offered app developers the facility to use both languages in the same project. This is not just helpful in case of developing an iOS app using Swift from scratch, but also in upgrading their existing app to Swift using Objective-C code.

While you are now familiar with the philosophical differences between the two iOS application development languages, let’s move to the differences while practical implementation.

SWIFT VS OBJECTIVE-C: MAJOR DIFFERENCES BETWEEN THE TITANS OF IOS DEVELOPMENT

With my experience with complex Objective-C codebase and Swift codebase, you will come across several upgrades to the existing concepts along with an introduction to various new elements making the app development process swiftly. Without making an ado, let’s have a look at everything you will find new/different in the war of swift vs objective c.

Optionals

When we talk about swift vs Objective-C performance, we can call methods on nil objects to obtain a zero value in Obj-C. We have to manually perform nil-checks to understand undefined behaviour in case of unexpected nil value. However, this issue can be solved by using Optional, a new concept introduced in Swift code. Optional allows functions which might not be able to return a meaningful value to return a value encapsulated in an optional or nil.

The Syntax of declaring Optional type is:

Public enum Optional<Wrapped> :_Reflectable, NilLiteralConvertible

Practically,  it can have either a value of Wrapped type or a non-existing value.

Swift renders the syntactic sugar for declaring types optional, so we can replace the Optional<String> with String?

There are primarily two ways to obtain wrapped value from the optional container:

Optional Chaining: Used in the case where the if-let conditional statement will receive a value only if it exists.
Forced Wrapping: Used when the optional declared variable is non-nil. If the value exists, it will provide the output without implementing conditions. But, in the other case, it will crash.
We can also find implicitly unwrapped optionals in Swift language, declared as String!

For example:

Class XClass

{

var aString: String

var bString: String!

var cString: String?

Init (string: String)

{

aString = string

}

}

Here,

A String can never be nil. It is crucial that this variable has a value during object initialization, otherwise the program will lead to a crash.
B String can be nil. However, if you attempt to access nil object, the program will crash.
C String can be nil and is supposed to be treated as a regular optional variable.
Extensions
The extensions and categories found in Obj-C are consolidated into a single entity, extensions in Swift language. Extensions add new functionality to an already existing class, enumeration, structure or protocol, and the best part is that you need not have access to the original source code to extend types.

Tuples
Besides Optionals, another new data type introduced in Apple’s new development language is Tuples. Tuples (in place user-defined datatype) are basically considered to group many values into a single compound group. It is the right element to consider if you think creating a model at a place might overkill and dictionary is not enough reader-friendly. To know more Tuples, refer this blog.

Generics
Generics is one of the most striking features of Swift programming language, and in fact, much of the Swift standard libraries are created with Swift code. The Generic code let the developers write flexible, reusable functions and types that can work with different set of type, subject to requirements defined. This minimizes the risk of duplication and enhances the code readability with a clear, abstracted approach.

According to my experience, Generics is hard to get at first, just like recursions. But, when you get hands on it, you will be able to unwind a whole new world of fixing tiresome logical problems.

Enumeration
In Objective-C code, enumerations are restricted to primitive types. For mapping integer enumeration values to that of strings for displaying output, you have to introduce an array or turn towards the switch control structure. However, you need not go through these hassles with Swift iOS app development language.

Swift offers varied new enumerations with more options. Swift enumerations can have associated values and Swift enumeration case can hold a predefined set of fields.  In fact, Swift enumerations can be recursive and can store raw values.

For example:

Subscripts
Subscripts can be seen as a medium to access information from a sequence, collection or list in classes, enumerations and structures without using a method. You can consider subscripts to set and retrieve values by index without creating separate methods for storing and retrieving. For example, you can access elements in an Array  instance as someArray[index] and elements in a Dictionary instance as someDictionary[key].

The syntax for declaring a Subscript is as follow:

subscript (index: Int) -> Int {

get {

//for declaring subscript value

}

set (newValue) {

//for defining values

}

}

Type Inference

Swift also proposed type safety for iOS application development, according to which a variable when declared with a particular type, its type will be static and unchangeable. The compiler will determine (or infer) what type your variable will be on the basis of values you assign.

For example:


Here, the compiler will show an error when you try to initialize with numeric values to a str2 variable (see below)

Functions
The Function syntax in Swift programming language is more flexible to define than that in complex Objective-C code style. In Swift, every function has a type which comprises of the function’s parameter types and returns type, which implies you can assign functions to a variable or pass it as a value to other functions (as shown in the example below):

Apart from this, Swift also let the app developers define default values to functional parameters.

Error Handling
Swift offers an entirely new approach to throwing, catching, circulating and manipulating recoverable errors at runtime. To get a glimpse of error handling in Swift, refer the blog.

Apart from these, various concepts that make Swift app development a win-win over Objective-C app development are:

Models
In the case of Swift, models are preferred to be structs rather than classes.

Protocols
In the very first of Apple WWDC videos, swift was introduced as “Protocol oriented language”. A protocol can be defined as a blueprint of methods, properties and other entities that suit a particular task/piece of functionality. They can be embraced by a class, enumeration or structure to facilitate an actual implementation of those requirements, and are far more powerful compared to Obj C with the features of providing default implementations, incorporating generics, etc.

As an iOS app developer, I prefer creating a protocol before defining a class as the most effectual practice to leverage the benefits of advanced Apple’s programming language.

Functional Programming Approach
Swift empower developers to use more of functional approaches for solving mundane problems than employing traditional loops or references types. Here, the perspective is to analyze a problem in terms of what the solution is, instead of determining how to get the solution as done in the traditional approach.

From my experience with both the iOS language, one thing that I noticed is that what we were doing by iterations using for loops in Objective-C can be done using the concept of Filter, Map and Reduce in Swift. To get in-depth information about these high-order functions in Functional programming, refer the blog.

STEP BY STEP GUIDE TO CONVERT A FULL OBJECTIVE-C APP TO SWIFT

Today, there are various tools to convert an app from Objective-C to Swift line-by-line. However, I advise not to use any. Although both the iOS languages are interoperable, their program paradigms are different. Migrating an app from Obj-C to Swift directly will bring a higher risk of using the wrong paradigms. Let me elaborate on this.

Swift, unlike its predecessor, is influenced by functional programming paradigm, which makes it heavily relies on immutability. For example, if you talk about arrays and dictionaries – these basic models are used to be a reference type in Objective-C, but they are value type in Swift, thus immutable. This implies that converting the Obj-C code to Swift subconsciously using any tool will make you face plenty of errors that are tough to debug. Besides, Swift has tons of new features (as already described above) which turns the algorithms/approaches more efficient and programs swiftly! In fact, it is the prime reason why Apple unveiled a new language rather than upgrading Obj-C.  With all these points into consideration, I highly recommend all to write a new app in Swift from scratch rather than going for line-by-line conversion from Obj-C to Swift.

Still, if you wish to convert a full Objective-C app to Swift, one tool that you can use is Swiftify. The tool eases the process of upgrading Obj-C code to Apple’s new programming language in one click; saving thousands of working hours. The feature of interoperability enables to integrated converted iOS code back to Objective-C without any hassle, which implies you can explore the myriad of options that Swift offers and then, integrate it back into your Obj-C project without rewriting everything at once.

Prepare Your existing app code for Conversion
It is always better, to begin with the latest Obj-C code. This is because Xcode avails a modern Objective-C converter that can help you with:

1. Changing id to instancetype wherever possible
2. Employing the correct enum macros
3. Upgrading to the more recent @property syntax

While the converter aids with the mechanics of analyzing and applying potential alterations, it does not depict the semantics of the code. So, it is advisable for all the iOS application developers to review everything manually once and then confirm the changes.

To use the converter, select Edit -> Refactor -> Change to Modern Objective-C syntax.

The process of Migrating Objective-C code to Swift
The most effectual approach to convert a full Objective-C app to Swift is, to begin with, one class at a time, especially a class without any subclass since you can’t subclass Swift classes in Obj-C.

Replace the .m and .h files related to the class with a single .swift file. With this, everything from the interface to implementation will automatically get into the Swift file. Besides, you need not to create a header file as Xcode automatically generate a header, if required.

Designing a Bridging Header File
When you add your first .swift file, you will find a prompt like the one shown below.

Click on the ‘Create Bridging Header’ option.

A Step-By-Step Guide

1. Choose a pair of .h and .m files that you want to convert into Swift. If you want to convert the whole project, leave the AppDelegate class for later.
2. Search for #import “MyViewController.h” throughout the code and remove it from the Objective-C Bridging Header File ([MyProject]-Bridging-Header.h).
3. Replace instances of #import “[filename].h” with #import “[MyProject]-Swift.h” in all .m files and put @class [filename] instead of #import “[filename].h” in all the .h files.
4. Transform the part of Obj-C files to Swift. This can be easily done using the Finder extension of ‘Swiftify for Xcode’. Otherwise, copy the content of .m and .h files to .swift and use the “Convert File to Swift” option available in the Swiftify Xcode Extension.
5. Replace the .h and .m files with converted .swift files in the project.
6. Compile the project and fix the conversion errors. While many issues will be easily managed using Xcode auto-fix suggestions, you can also rely on Swiftify to report and fix the errors appearing several times in the project.
7. Once done, build and run the project. If there arises the issue of ‘Class not Found’ followed by crashing, find all the references to it in the Storyboard Editor. Re-enter the class name in the Identity Inspector, save and try again.
8. If you are converting the entire project, you can transform AppDelegate class now. At this point, all the other files have been converted to Swift and so, if there are no Obj-C files left in the target, you can easily delete the main.m and .pch(precompiled header) file.

Which practice do you prefer – create a new iOS app in Swift from scratch or convert  Objective-C to Swift fully? Share your views via the comment section below.

Gurdeep Singh
Product Innovation Team
In search for strategic sessions?.
Let us understand your business thoroughly and help you
strategies your digital product.