Logo for tanaschita.com

Objective-C basics for Swift developers

Quick reference and cheatsheet for Swift developers learning Objective-C

06 Feb 2021 · 6 min read

Swift is a powerful programming language that was released at the WWDC 2014 as a replacement for Objective-C. But with many existing apps written in Objective-C still out there, knowing or at least having a basic understanding of Objective-C can be useful.

This post serves as a quick reference on Objective-C for Swift Developers who want to learn or look up Objective-C specifics.

Two dogs playing
Old buddies Obji and Swifty

Variables

Swift

For defining variables, Swift offers the let keyword for constants and the var keyword for variables. Swift offers type inference and optional data types.

let name = "Swifty" // declaring and assigning a constant
var age: Int? // declaring an optional Int variable
age = 7 // reassigning the variable
age = nil // nullifying the variable
var year = 2014 // the compiler automatically infers the `Int` type
let fruits = ["apple", "orange"] // desclaring and assigning an array of strings

Objective-C

Objective-C does not support type inference, we always have to explicitly specify the variable's type. There are basic types like int, float, char etc. and object types like NSString, NSNumber etc.

Objective-C does not have an explicit optional type, all object types can be nullified.

NSString const *name = @"Obji"; // declaring and assigning a constant
NSNumber *age; // declaring a variable
age = 7; // reassigning the variable
age = nil; // nullifying the variable
NSArray<NSString*> *fruits = @[@"apple", @"orange"]; // desclaring and assigning an array of strings

The syntax in Objective-C may be confusing at first. Let's break it down:

  • Every NSString in Objective-C is prefixed with an @.
  • With the asterisk * we’re saying that we are creating a pointer to an object. It's just like declaring a reference type variable in Swift.
  • When creating arrays, Objective-C offers a short syntax with leading @ before the [].

Properties

In both languages, declaring properties works basically the same way as declaring variables. The difference is that we declare them as part of a type and can apply additional attributes to them, for example for access control or memory management.

Swift

In Swift we can declare stored properties for classes, structures or enumerations. By default, Swift properties are strong and have the internal access level.

class Child {
private let firstName: String // declaring a private constant property
private(set) var lastName: String // declaring a read-only property
var age: Int // declaring an internal property
weak public var parent: Parent? // declaring a weak public property
}

Objective-C

In Objective-C properties are used only as part of a class. They begin with the @property keyword followed by comma-separated attributes for memory management and access control.

@property NSString *firstName; // declaring a strong property
@property (readonly) NSString *lastName; // declaring a read-only property
@property (weak) Parent *parent; // declaring a read-only property

The visibility of Objective-C properties is not achieved with attributes but with where we place them in our class declarations. We will look at that in the classes section.

Methods

Swift

In Swift we can define methods on classes, structures and enumerations.

// method declaration with no return type and no parameters
func emptyCard()
// method declaration with two parameters and a return value
func search(_ searchQuery: String, category: String) -> [Tea]
// default parameters
func walk(withSpeed speed: Int = 20)
// method implementation
func search(_ searchQuery: String, category: String) -> [Tea] {
return []
}
// calling a method
let results = teaShop.search("camomile", category: "herbs")

Objective-C

In Objective-C classes are the only types that can define methods. Default parameters are not supported.

// method declaration with no return type and no parameters
// `void` represents the absence of a type.
- (void)emptyCard;
// method declaration with two parameters and a return value
- (NSArray<Tea *> *)search:(NSString *)searchQuery category:(NSString *)category
// implementation of a method with two parameters and a return value
- (NSArray<Tea *> *)search:(NSString *)searchQuery category:(NSString *)category {
return [];
}
// calling a method
NSArray<NSString *> *results = [teaShop search:@"camomile" category:@"herbs"];

Classes & structs

Swift

In Swift we differentiate between classes as reference types and structs as value types.

import Foundation
class TeaShop {
// define public & private properties & methods
}
struct Tea {
// define public & private properties & methods
}
// using a class
let shop = TeaShop()
// using a struct
let tea = Tea()

Objective-C

In Objective-C we need two separate files to define a class - the class header as .h file and the class implementation as .m file. All classes are derived from the base class NSObject which provides basic methods for memory allocation and initialization.

TeaShop.h

@import Foundation;
@interface TeaShop : NSObject
// public properties & method definitions
@end

TeaShop.m

#import "TeaShop.h"
@interface TeaShop ()
// private properties & method definitions
@end
@implementation TeaShop {
// private instance variables
}
// methods implementation
@end

Creating a new object in Objective-C is a two-step process. First, we allocate memory for the object and then initialize it.

TeaShop *shop = [[TeaShop alloc] init];
// or the shorter version, that will call `alloc` and `init` for us
TeaShop *shop = [[TeaShop new];

Structs are also supported, but only as a C construct which can be used in Objective-C since Objective-C is a superset of C.

// Declaration of a struct
struct Position
{
int x;
int y;
};
// Usage of a struct
struct Position position;
position.x = 5;
position.y = 10;

Enums

Swift

Like structs, Swift enums are first-class types which provide a lot of flexibility with features like associated types, computed properties, custom initializers and more.

enum TeeCategory {
case herbal
case green
case fruits
}
let category = TeeCategory.green

Objective-C

Similarly to structs, there are only C enums available for Objective-C. These are a lot less flexible than the Swift enums.

typedef NS_ENUM(NSInteger, TeeCategory) {
TeeCategoryHerbal,
TeeCategoryGreen,
TeeCategoryFruits
} TeeCategory;
TeeCategory category = TeeCategoryFruits;

Extensions

Swift

In Swift we can add new functionality to an existing class, struct, enum or protocol by using an extension.

extension String {
var asURL: URL? {
URL(string: self)
}
}

Objective-C

In Objective-C we can use categories to add new functionality to an existing class. Like a class, a category consists of two files, a header and a implementation file.

NSString+URL.h

@interface NSString (URL)
-(NSURL*)toURL;
@end

NSString+URL.m

#import "NSString+URL.h"
@implementation NSString (URL)
-(NSURL*)toURL {
return [[NSURL alloc] initWithString:self];
}
@end

Conclusion

This guide only presented basic Swift and Objective-C usage. Of course, there is a lot more to explore in both languages like protocols, generics, error handling etc. I hope, this guide has given you a good foundation to dive deeper into the more advanced language features.