Swift introduces a variety of features that are handy in writing simple, safe, and readable code. This article will help you to find some of the best swift features that every iOS developer should know. Ready? Let us begin.
Swift 4 introduces Codable which combines the two protocols Encodable and Decodable into one. It will help us to serialize or deserialize custom data types easily without writing any special code.
Consider the example.
{
"name": "John Doe",
"country": "USA",
"gender": "Male"
}
Create a Struct Person, with the same format as of above json.
struct Person : Codable {
let name: String?
let age: Int?
let gender: String?
}
We have marked this struct conforming to Codable protocol, with that addiction we can convert it to a Data representation of JSON like this:
if let encoded = try? JSONEncoder().encode(per) {
}
Swift will automatically encode all the properties inside our Person data type – we don’t need to do anything extra. This encoded data can be decoded as:
if let encoded = try? JSONEncoder().encode(per) {
print(encoded)
do {
if let json = String(data: encoded, encoding: .utf8) {
print(json)
}
let decoded = try JSONDecoder().decode(Person.self, from: encoded)
print(decoded)
} catch let error {
print(error.localizedDescription)
}
}
Generic code provides flexible, reusable functions and types that can work with any type, subject to requirements that you define. It avoids duplication and provides abstraction.
Let us consider an example, we can write a method for splitting an array into multiple arrays.
func splitArray<T>(array: [T], splitSize: Int) -> [[T]] {
if array.count <= splitSize {
return [array]
} else {
return [Array<T>(array[0..<splitSize])] + splitArray(array:
Array<T>(array[splitSize..<array.count]), splitSize: splitSize)
}
}
If the input array is [1,2,3,4,5,6,7] and splitSize is 2 then the output will be [[1, 2], [3, 4], [5, 6], [7]] since generics are used the array be of String, Int or any type of objects.
Consider another example.
func callAPI<T: Codable>(withPath url: URL, params : [(String, String)],
andMappingModel model: T.Type, callback: @escaping (_ result: Result<T, Error>) ->
Void ) {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
do {
let jsonDecoder = JSONDecoder()
let responseModel = try jsonDecoder.decode(model, from: data!)
callback(Result.success(responseModel))
} catch {
callback(Result.failure(error))
}
}
task.resume()
}
In the above example, we can pass any type of codable object for mapping the JSON data since the protocol is specified to the generic only objects which conform to codable can be passed in the method. This method is used to serialize any kind of JSON string with its related codable class.
We can call this method as:
ApiMapper.sharedInstance.callAPI(withPath: urlString, params: params,
andMappingModel:Person.self) { (result) in
}
We use \n inside the string for multiline strings. However, swift 4 introduces new syntax for multiline strings that allow us to add line breaks freely. It uses quotes instead of escaping.
For starting a multi-line string literal, we have to add three double quotes:””” and then press return before each new line. Then we can write the string as long as we want with variables and line breaks, ending the string by pressing return and then adding three double-quotes.
let multiLineString = """
lineOne
lineTwo
lineThree
"""
print("multiLineString: \(multiLineString)")
The above example will create a string with three lines:
multiLineString: lineOne
lineTwo
lineThree
Swift 4.1 introduces an Equatable protocol which allows us to compare one instance of a type against another. If we say 5==5 that means Int conforms to Equatable, i.e. it implements a function that describes what == means for the two instants of Int.
Consider an example,
struct Book {
var name: String
var authortName: String
var price: Int
}
if you have two instances of Book and you need to confirm they are identical then you need to compare all the 3 properties name,authorName, and price as:
struct Book: Equatable {
var name: String
var authortName: String
var price: Int
}
static func ==(lhs: Book, rhs: Book) -> Bool {
return lhs.name == rhs.name && lhs.authortName == rhs.authortName &&
lhs.price == rhs.price
}
}
Swift 4.1 can synthesize this conformance of Equatable by automatically creating this == method which compares all of its properties. i.e. we just need to add the Equatable as a protocol for our type like,
struct Book: Equatable {
var name: String
var authortName: String
var price: Int
}
Apple introduced a new swift feature, random API that is native to swift and cryptographically secure so that you can avoid the usage of arc4random_uniform() in most cases to get randomness. We can generate random numbers simply by calling the method random().
let randomInt = Int.random(in: 1..<10)
let randomFloat = Float.random(in: 1..<10)
let randomCGFloat = CGFloat.random(in: 1..<10)
let randomDouble = Double.random(in: 1..<10)
let randomBool = Bool.random()
The toggle() method in swift 4.2 allows us to toggle boolean values. This will avoid the potential typing errors that could be caused using manual negation.
extension Bool {
mutating func toggle() {
self = !self
}
}
var isOn = false
isOn.toggle()
Swift 4.2 includes support for shuffling arrays using shuffle() and shuffled() based on whether we want an in-place shuffle or not. The in-place shuffle can be done by Shuffle() like,
var fruits = [“Apple”, “Orange”, “Grapes”]
fruits.shuffle()
The shuffled() method will return a shuffled array.
fruits.shuffled()
Swift 5 came up with a new method count(where:) allows us to get the number of items in a sequence that satisfy a particular condition.
let scores = [1, 3, 8, 2, 5, 6, 2, 10]
let count = scores.count(where: { $0 > 5 })
Swift 5 modifies the working of try? so that nested optionals are flattened to become regular optionals. This new behavior is the same as optional changing and conditional
typecasts. It allows us to use optional chaining as many times in a single line of code without multiple nested optionals. Also the optional chaining with as? will have only one level of optionality.
//Swift 4.2 : String??
//Swift 5 : String?
let messages = try? person?.getName()
Instead of using the map, reduce, and filter to filter out nil or odd values, Swift 5 introduces a new method compactMapValues(). It combines the compactMap(🙂 function of arrays with the mapValues(🙂 function of dictionaries for effective mapping and filtering values.
Swift 5 gives us the ability to specify a custom string delimiter using the hash symbol, #(hashtag or pound symbol). Whenever we use # with a string, it changes the way of swift understanding the special character in the string:
● \ is no longer acting as an escape character.
● \n becomes a backslash followed by n instead of a line break.
● (variable) will be included as those characters in the string rather than using string interpolation.
let name = "Taylor"
let greeting = #"Hello, \(name)!"#
print(greeting) // Hello, \(name)!
let greeting = #"Hello, \#(name)!"#
print(greeting) // Hello, Taylor!
I hope now you’ve learned some easy, but efficient swift features that’ll help you write better iOS code and speed up iOS application development 🙂