iOS – Are 20 Quick Valuable Concepts Best way to Learn Swift?

Hello Readers, CoolMonkTechie heartily welcomes you in this article (Are 20 Quick Valuable Concepts Best way to Learn Swift? ).

In this article, We will discuss 20 quick valuable concepts which is the best way to learn swift and helps to build iOS applications. We’ll need Swift Foundation Concepts as we start building apps. It means that we introduce each topic in a way. This provides enough background to understand the foundation concepts.

A famous quote about learning is :

The beautiful thing about learning is that nobody can take it away from you.

So Let’s begin.


1. Hello World

It is common to start any tutorial for a new language with the Hello World example so we’ll start out by showing how easy this is to do in Swift:

print("Hello World!")      // Prints "Hello World!" to the output window in Xcode

To make this a little more personal, let’s look at one of the handy features of Swift (called string interpolation) where we can insert values into strings using the \(...) syntax. Below, we’ve inserted name into the middle of our string:

let name: String = "World"
print("Hello \(name)!")     // Prints "Hello World!"


2. When to use let vs var

We’ll notice in the example above we’ve used let to create the new variable for the name “Bob”. In Swift, we’ll choose from the following 2 options when creating a new variable:

  • let => Use let when we are defining a constant (a value that will not change)
let numberOfContinents: Int = 7   // Seven continents will not change so we've used "let"
  • var => Use var when we are defining a variable (a value that might change)
var continentsVisited: Int = 2   // Continents visited increases over time so we've used "var"

In general, it is considered a best practice to use constants (let) whenever possible.


3. Numbers

The two most common types of numbers we’ll use in Swift are integers (Int) and doubles (Double):

Integers are whole numbers with no fractional component:

let minValue: Int = -42
let maxValue: Int = 55 

Doubles can have a fractional component:

let pi: Double = 3.14159
let billAmount: Double = 10.25


4. Strings

Strings represent a series of characters:

let hello: String = "Hello"
let world: String = "World"

We can use string interpolation to construct new strings:

let helloWorld: String = "\(hello) \(world)"    // "Hello World"

Or we can use the + operator to combine strings:

let helloWorld: String = hello + " " + world    // "Hello World"


5. Booleans

Boolean is a very simple type in Swift as it can only ever be true or false:

let swiftIsCool: Bool = true
let iMissObjectiveC: Bool = false 


6. Arrays

Arrays store a list of values that must be of the same type. Below we’ve kept track of the previous bill amounts (which is a list of doubles):

// Notice how we've used "var" here since we want to append new items to the array
var previousBillAmounts: [Double] = [10.25, 21.32, 15.54]

To add a new bill to the array:

previousBillAmounts.append(52.45)    // Result: [10.25, 21.32, 15.54, 52.45]

To check on how many bills there are in the array:

let count = previousBillAmounts.count            // Result: 4

Or to check the first bill amount in the array:

let firstBillAmount = previousBillAmounts[0]    // Result: 10.25


7. Dictionaries

Much like we might use a real-world dictionary to look up the definition for a word, you can use the dictionary data structure in Swift to create associations between keys (the word in the real-world dictionary) and values (the definition in the real-world dictionary).

For example, let’s say we want to keep track of the ages of people that are using our app. This will best done using the following dictionary:

var people: [String: Int] = [
                              "Bob": 32,
                              "Cindy": 25
                            ]

Here, the key is the name of the person and the value is the person’s age.

Later on if we want to find out Bob’s age, we can look it up by doing:

let bobsAge = people["Bob"]

If we get a new user we can easily add them to our dictionary using the following syntax:

people["Dan"] = 56


8. Specifying Types

In most of the examples in this article, we are explicit with the types of our constants and variables. Explicit typing looks something like:

let name: String = "Bob"   // Explicitly designating "name" to be of type "String"

However, Swift is smart enough to infer the type for us in a lot of cases. The short example of previous example is:

let name = "Bob"   // Swift infers "name" is of type "String" since "Bob" is a String

In cases where Swift can infer the type, it’s not necessary to be explicit with the types for our constants and variables. We just do it in this guide so that the examples are easier to follow.


9. Any and AnyObject

Swift has two special “catch all types” that come in handy when a more specific type cannot determine.

  • AnyObject can represent an instance of any class type.
  • Any can represent an instance of any type at all.

In general, it’s a best practice to be as specific with our types as possible and avoid the use of AnyObject and Any, but they become particularly helpful when interacting with Objective-C code that is less strict on typing.


10. Optionals

Optionals is a very important concept in Swift and it means to improve the safety of Swift code. By simply placing a question mark (?) after any type, it declares that variable to be optional. An optional type allows that variable to exist in one of the following two states:

  1. There is a value and it equals x
  2. There isn’t a value at all

Let’s look at an example to make this more clear. Consider the following 2 examples where we are trying to convert a String to an Int:

// Example 1 (Conversion succeeds)
let input: String = "123"
let optionalConvertedInput: Int? = Int(input)  // optionalConvertedInput = 123

// Example 2 (Conversion fails - input is not a number)
let input: String = "123abc"
let optionalConvertedInput: Int? = Int(input)  // optionalConvertedInput = nil

Swift requires optionalConvertedInput to be of type Int? (or “optional Int”) so that it is explicit that convertedInput might not contain a value (in the case when the conversion fails). If we were to declare convertedInput as simply Int, we’d get a compile error.

There’s a handy syntax in Swift that we’ll use quite often when working with optionals. If we wanted to use the value of optionalConvertedInput later on in our code, we’d have to first check to make sure it’s not nil. We can do so using the following code:

if let convertedInput = optionalConvertedInput {
   // Code that gets executed when optionalConvertedInput is NOT nil
} else {
   // OptionalConvertedInput IS nil, do something else
}

In other languages like Java, NullPointerException is a common source of crashes. This exception fires when a null reference accesses. Swift’s Optionals go a long way to reduce this type of programming error.


Optionals in string interpolation

When using optionals in string interpolation, the value with either be Optional(...) or nil without being explicitly unwrapped. When the inner value needs, the optional must unwrap.

let maybeString: String? = "value"

print("\(maybeString)")  // prints -> Optional("value")
print("\(maybeString!)")  // prints -> "value"


11. Functions

Functions in Swift are very similar to other languages. The simplest function in Swift can write as:

// This prints "Hello!" to the output window
func printHello() {
    print("Hello!")
}

// Calls this function
printHello()

We can extend this function to be a little more personable by taking in a name and returning the greeting instead of printing it out:

// Takes in a "personName" parameter of type String and returns the greeting as a String
func sayHello(personName: String) -> String {
    // Implicitly returns when there is a single statement
    "Hello \(personName)!"
}

// Calls this function
let greeting: String = sayHello("Bob")

Things get a little more interesting when we start to have multiple parameters as Swift has the concept of external and local parameter names. An external parameter name is used to label arguments passed to a function call. A local parameter name is a name used in the implementation of the function.

// "to" + "and" are the external parameter names
// "person" + "anotherPerson" are the local parameter names
func sayHello(to person: String, and anotherPerson: String) -> String {
    "Hello \(person) and \(anotherPerson)!"
}

// Calls this function using the "external" parameter names
let greeting: String = sayHello(to: "Bill", and: "Ted")


12. Control Flow


Conditional Statements

If statements are very similar to other languages and can express as:

let temperatureInFahrenheit: Int = 90

if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
} else {
    print("It's not that cold. Wear a t-shirt.")
}


Loops

The two most common types of loops we’ll need in Swift are for loops and for-in loops.

For loops work well when we want to do something until a particular condition is met (in the case below until index >= 3):

// Simple for loop that prints "Hello" 3 times
for var index = 0; index < 3; index++ {
    print("Hello")
}

C-style for loops deprecated and will remove in future versions of Swift. For-in loops are preferred instead. The above example could be re-written as:

for _ in 0..<3 {
          print("Hello")
      }

For-in loops come in really handy when we want to do something to each item in a collection (such as an array):

let names = ["Anna", "Alex", "Brian", "Jack"]

// Loops over each name in "names" and prints out a greeting for each person
for name in names {
    print("Hello, \(name)!")
}

Sometimes, we want to loop over each item in an array and also keep track of the index of the item. Array’s enumerated() method can help you achieve this:

let names = ["Anna", "Alex", "Brian", "Jack"]

for (index, value) in names.enumerated() {
    print("Item \(index + 1): \(value)")
}


13. Classes

Classes are the building blocks of our app’s code. We define properties and methods to add functionality to our classes by using the same syntax as for variables and functions.

Below we can find a Person class that is meant to show an example of the types of things we’ll want to do when building our classes.

class Person {
	
    // Custom initializer - takes in firstName and lastName
    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName

        // Increment type property each time a new person is created
        Person.numberOfPeople++
    }
	
    // *** Properties ***
	
    // Stored Property - Stored as part of the current instance of the class
    var firstName: String
    var lastName: String

    // Computed Property - computes "fullName" from "firstName" and "lastName"
    var fullName: String {
    	get {
            "\(firstName) \(lastName)"
    	}
    }

    // Type Property - Single instance for all instances of the class,
    // similar to a static property in Java
    static var numberOfPeople = 0   
    
    // *** Methods ***
    
    // Instance Method
    func greet() {
    	// Notice the use of "self" - self refers to the current instance and 
        // is similar to "this" in Java
    	print ("Hello \(self.firstName)")
    }
    
    // Type Method
    class func printNumberOfPeople() {
    	print("Number of people = \(Person.numberOfPeople)")
    }
}

// ... Using the Person Class ...

// Create a new instance of the Person class
let bob = Person(firstName: "Bob", lastName: "Smith")

// Call instance method
bob.greet()   // Prints "Hello Bob"

// Accessing properies
print("Bob's first name is: \(bob.firstName)")  // Prints "Bob's first name is: Bob"
print("Bob's full name is: \(bob.fullName)")    // Prints "Bob's full name is: Bob Smith"

// Call type method
// Prints "Number of people = 1" (since we've only created one Person)
Person.printNumberOfPeople()


14. Protocols

Protocols are similar to interfaces in other languages. Think about a protocol as a contract. The contract includes a set of methods that must be implemented. Any classes that choose to implement a protocol sign this contract and implement all the methods that are in the protocol.

Let’s say we have the following protocol (MyFriendlyGreeterProtocol) that defines 2 methods sayHello() and sayBye():

protocol MyFriendlyGreeterProtocol {
    func sayHello()
    func sayBye()
}

Any classes that implement this protocol (you implement a protocol by adding its name after the class defintion as shown below), must implement both of these methods:

class MyEnglishPerson: MyFriendlyGreeterProtocol {
    func sayHello() {
        print("Hello!")
    }

    func sayBye() {
        print("Bye!")
    }
	
    // ... other methods for this class ...

}

class MySpanishPerson: MyFriendlyGreeterProtocol {
    func sayHello() {
        print("Hola!")
    }

    func sayBye() {
        print("Adios!")
    }
	
    // ... other methods for this class ...
}

There is a lot more you can do with protocols as they form one of the key design patterns in iOS. The code above merely shows how to get started with the syntax for protocols.


15. Swift Closures

Closures are self-contained blocks of code that can be passed around and used in our code. These are similar to blocks in Objective-C and lambdas in other programming languages.

Swift Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as “closing” over those constants and variables. Swift handles all of the memory management of capturing for you.

Closure Example:

Example: A function called makeIncrementer which contains a nested function

Here’s an example of a function called makeIncrementer, which contains a nested function called incrementer. The nested incrementer() function captures two values, runningTotal and amount, from its surrounding context. After capturing these values, incrementer is returned by makeIncrementer as a closure that increments runningTotal by amount each time it is called.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

The return type of makeIncrementer is () -> Int. This means that it returns a function, rather than a simple value. The function it returns has no parameters, and returns an Int value each time it is called.

The makeIncrementer(forIncrement:) function defines an integer variable called runningTotal, to store the current running total of the incrementer that will be returned. This variable is initialized with a value of 0.

The makeIncrementer(forIncrement:) function has a single Int parameter with an external name of forIncrement, and a local name of amount. The argument value passed to this parameter specifies how much runningTotal should be incremented by each time the returned incrementer function is called.

makeIncrementer defines a nested function called incrementer, which performs the actual incrementing. This function simply adds amount to runningTotal, and returns the result.

When considered in isolation, the nested incrementer() function might seem unusual:

func incrementer() -> Int {
    runningTotal += amount
    return runningTotal
}

The incrementer() function doesn’t have any parameters, and yet it refers to runningTotal and amount from within its function body. It does this by capturing a reference to runningTotal and amount from the surrounding function and using them within its own function body. Capturing by reference ensures that runningTotal and amount do not disappear when the call to makeIncrementer ends, and also ensures that runningTotal is available the next time the incrementer function is called.

Example: a function called makeIncrementer in action

Here’s an example of makeIncrementer in action:

// This example sets a constant called incrementByTen to refer to an //incrementer function that
// adds 10 to its runningTotal variable each time it is called.

let incrementByTen = makeIncrementer(forIncrement: 10)

incrementByTen()  // returns a value of 10
incrementByTen()  // returns a value of 20
incrementByTen()  // returns a value of 30


16. Type Casting (as, as?, as!)

Type casting changes the type of a particular instance to another compatible type. There are 3 ways to accomplish this with Swift:

  1. Guaranteed conversion with as : This is the safest cast. It will never fail since the compiler can guarantee the cast will work. Use this when you are upcasting from a child class to its parent or doing something like 1 as Float.
// Guaranteed conversion as the compiler can verify this will succeed
let myFloat = 1 as Float

// Guaranteed conversion as upcasting from a type to its parent type is safe 
// UIView is a parent of UITableView
let myView = myTableView as UIView

2. Conditional conversion with as? : This is a cautious cast. If the cast fails, it will return nil. This is needed when downcasting from a parent type to a child type.

// If myView is actually a tableView, the downcast will succeed, otherwise it will fail safely
if let myTableView = myView as? UITableView {
    print("The downcast succeeded!")
} else {
    print("The downcast failed!")   	   
}

3. Forced conversion with as! : This is a dangerous cast that you should avoid using. If the cast fails, this will crash our app. Use this cast carefully.

// DANGEROUS: If myView is actually a tableView, the downcast will succeed
// Otherwise it will crash the app
let myTableView = myView as! UITableView


17. Understanding the Exclamation Mark (!)

There are various places you might come across an exclamation mark in Swift code. The following examples are meant to capture the major types of use cases for the exclamation mark operator that can cause confusion when first learning Swift.

When getting the actual value out of an optional (called unwrapping an optional):

let possibleString: String? = "An optional string."

// DANGEROUS: possibleString must NOT be nil or this will crash
let forcedString: String = possibleString! 

// SAFE: Will only enter the if clause if possibleString is NOT nil
if let actualString = possibleString {
    // do something with actualString
}

// SAFE: Generally preferred alternate syntax to "if let" that can exit early
guard let actualString = possibleString else {
    // exit early or throw exception
}
// do something with actualString

When type casting (called forced conversion):

// DANGEROUS: If myView is actually a tableView, the downcast will succeed
// Otherwise it will crash the app
let myTableView = myView as! UITableView

When defining variables that are initially nil but get set soon afterwards and are guaranteed not to be nil after that (called implicitly unwrapped optionals):

let assumedString: String! = "An implicitly unwrapped optional string."

// no need for an exclamation mark since assumedString is an implicitly unwrapped optional
let implicitString: String = assumedString


18. Property Observers

A very useful inclusion of the Swift language is Property Observers. While the language might sound complex, it’s actually a literal explanation of what it does. It allows you to observe properties and respond to impending or finished property changes. It’s part of Apple’s goal to make Swift a cleaner language because a developer merely has to keep any logic related to updating properties in one convenient place.

Let’s look at an example.

Assume we have a Fitness tracking application and whenever a user enters their weight, we calculate and display their BMI to them.

Without property observers, and keeping in good practice (since BMI is calculated and not set in initialization), we might have a class like this –

Swift

class Profile {
    let height: Double
    var weight: Double
    private var BMI: Double
    
    init(weight: Double, height: Double) {
        self.height = height
        self.weight = weight
        self.BMI = weight / (height*height)
    }
    
    func getBMI() -> Double {
        self.BMI
    }
    
    func updateBMI() {
        self.BMI = weight / (height*height)
    }
}  

In a view where we ask the user to enter their new weight, we would call profile.updateBMI() after the new weight is set. Isn’t this a little tedious? It’s almost a trap for developers. We have to actively remember that we should update our BMI every time we update our weight.

Thankfully, with property observers, we don’t have to actively watch every property change as a developer. Our class becomes –

class Profile {
    let height: Double
    var weight: Double {
        didSet {
            updateBMI()
        }
    }
    private var BMI: Double
    
    init(weight: Double, height: Double) {
        self.height = height
        self.weight = weight
        self.BMI = weight / (height*height)
    }
    
    func getBMI() -> Double {
        self.BMI
    }
    
    func updateBMI() {
        self.BMI = weight / (height*height)
    }
}  

It might not look like much, but now whenever we update BMI, we don’t have to worry about calling updateBMI() and to be honest, we can clean this up even more by making BMI private(set), changing Profile to a struct and adding a mutating func.

struct Profile {
    let height: Double
    var weight: Double {
        didSet {
            updateBMI()
        }
    }
    private(set) var BMI: Double
    
    mutating private func updateBMI() {
        BMI = weight / (height * height)
    }
}  

What is mutating we ask? Well, normally Struct’s are read only. This is because in order for them to be fast, they need to take up space on Stack instead of Heap. A simple way to explain this is to imagine that Stack is writing with a Pen and Heap is writing with a Pencil. Some of you might think “well what’s the big deal? they both write.” But think about all the extra work that comes with a Pencil – We need an eraser, we have to clean the eraser off the paper and can end up using more material if we edit a lot. A pen, on the other hand, we just write (we’re assuming you’re not using an erasable pen or white-out) and it’s set.

Mutating gives us the ability to say, “Hey, this Struct will be read-only, but if I make it a variable, I might want to update its properties, so please give me the ability to edit that Struct”.

There’s a little more to this under the hood, but Structs tend to be pretty thread-safe, so we can assume every Struct exists by itself and it’s pretty safe to edit like this.


Other Property Observers

There are other property observers for every stage of a state change – willSet, set/get are included. willSet has the added ability of being able to compare newValue to the original value (called the property name).

A few hints about where didSet can be quite powerful is when dealing with network data and data sources. When a user has the ability to get objects from a server with a regular network call, a search and tapping a keyword, it can be useful if the var dataSource: [Models] has didSet to reload the data of the view. That way we won’t have to do it manually.


19. Working with JSON

A lot of the time when working with REST API’s (like Instagram, Twitter, etc), the data that comes back will be JSON. JSON is a human readable data format (very similar to XML).

Below is an example of JSON that simulates the type of JSON. We might get back when using an endpoint that returns movies and their ratings:

  • An open curly brace means the start of a dictionary
  • An open bracket means the start of an array
{
    "status": "OK",
    "movies": [
        {
            "title": "Whiplash",
            "rating": 8.5
        }, 
        {
            "title": "Feast",
            "rating": 5.2
        }, 
        {
            "title": "Kung Fury",
            "rating": 7.1
        }
    ]
}


Below is an example of how we extract the movies and ratings from that response:

// data returned from the network response will typically be of type
// NSData (which is a buffer of bytes)
let responseData: NSData = // ... some value retrieved from the network response ...

// Wrap our code in a do catch as our code might throw an exception which we need to handle
do {
    // Start by converting the NSData to a dictionary - a dictionary for the entire response
    if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(responseData,
        options:NSJSONReadingOptions(rawValue:0)) as? [String:AnyObject] {

            // Dip inside the response to find the "movies" key and get the array of movies
            if let movies = responseDictionary["movies"] as? [AnyObject] {

                // Get each movie dictionary from the array of movies
                for movie in movies {
                
                    // Use the movie "title" key and "rating" key to get their values
                    if let title = movie["title"] as? String {
                        if let rating = movie["rating"] as? Double {
                            print("Title:\(title), rating:\(rating)")
                        }
                    }
                }
            }
    }
} catch {
    print("Error parsing JSON")
}


20. Playgrounds

Xcode includes a very useful tool for learning Swift called “Playgrounds”. It’s very easy to create a new playground through Xcode.

Once inside a playground, we can write Swift code and see it run immediately (without needing to build and run a project each time). This allows you to try out different syntaxes and test out our code before including it in our app.

We highly recommend checking out Playgrounds while we are learning Swift.

That’s all about in this article.

Related Other Articles / Posts


Conclusion

In this article, We discussed 20 quick valuable concepts which are the best way to learn swift and help to build iOS applications.

Thanks for reading! I hope you enjoyed and learned about the 20 quick valuable Swift Foundation Concepts. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow other website and tutorials of iOS as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

A Short Note – iOS Best Practices And Swift Coding Standards With Code Organization, Spacing and Comments

Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (iOS Best Practices And Swift Coding Standards With Code Organization, Spacing and Comments).

In this note series, we will learn about iOS Best Practices and Swift Coding Standards With Code Organization, Spacing and Comments. Coding standards act as a guideline for ensuring quality and continuity in iOS code. We will discuss about iOS best practices and swift coding standards with Code Organization, Spacing and Comments which will helps to ensure our code as efficient, error-free, simple ,easy maintenance enabled and bug rectification.

So Let’s begin.

Code Organization

We can use extensions to organize our code into logical blocks of functionality. Each extension should be set off with a // MARK: – comment to keep things organised.

Protocol Conformance

We can prefer adding a separate extension for the protocol methods when adding protocol conformance to a model. This keeps the related methods grouped together with the protocol and can simplify instructions to add a protocol to a class with its associated methods.

Preferred :

class MyViewController: UIViewController {

  // class stuff here

}

// MARK: - UITableViewDataSource

extension MyViewController: UITableViewDataSource {

  // table view data source methods

}

// MARK: - UIScrollViewDelegate

extension MyViewController: UIScrollViewDelegate {

  // scroll view delegate methods

}

Not Preferred :

class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate {

  // all methods

}

Since the compiler does not allow us to re-declare protocol conformance in a derived class, it is not always required to replicate the extension groups of the base class.

This is especially true if the derived class is a terminal class and a small number of methods are being overridden. When to preserve the extension groups is left to the discretion of the developer.

For UIKit view controllers, consider grouping lifecycle, custom accessors, and IBAction in separate class extensions.

Unused Code

Unused (dead) code, including Xcode template code and placeholder comments should be removed. An exception is when our tutorial or book instructs the user to use the commented code.

Aspirational methods not directly associated with the article whose implementation simply calls the superclass should also be removed. This includes any empty/unused UIApplicationDelegate methods.

Preferred:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

  return Database.contacts.count

}

Not Preferred:

override func didReceiveMemoryWarning() {

  super.didReceiveMemoryWarning()

  // Dispose of any resources that can be recreated.

}

override func numberOfSections(in tableView: UITableView) -> Int {

  // #warning Incomplete implementation, return the number of sections

  return 1

}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

  // #warning Incomplete implementation, return the number of rows

  return Database.contacts.count

}

Minimal Imports

Import only the modules a source file requires. For example, don’t import UIKit when importing Foundation will suffice. Likewise, don’t import Foundation if we must import UIKit.

Preferred:

//1
import UIKit

var view: UIView

var deviceModels: [String]

//2
import Foundation

var deviceModels: [String]

Not Preferred:

//1

import UIKit

import Foundation

var view: UIView

var deviceModels: [String]

//2

import UIKit

var deviceModels: [String]

Spacing

Indent using 2 spaces rather than tabs to conserve space and help prevent line wrapping. Be sure to set this preference in Xcode and in the Project settings as shown below:

  • Method braces and other braces (if/else/switch/while etc.) always open on the same line as the statement but close on a new line.
  • There should be exactly one blank line between methods to aid in visual clarity and organization. Whitespace within methods should separate functionality, but having too many sections in a method often means we should refactor into several methods.
  • There should be no blank lines after an opening brace or before a closing brace.
  • Colons always have no space on the left and one space on the right. Exceptions are the ternary operator ? :, empty dictionary [:] and #selector syntax addTarget(_:action:).
  • Long lines should be wrapped at around 70 characters. A hard limit is intentionally not specified.
  • Avoid trailing whitespaces at the ends of lines.
  • Add a single newline character at the end of each file.

We can re-indent by selecting some code (or Command-A to select all) and then Control-I (or Editor ▸ Structure ▸ Re-Indent in the menu). Some of the Xcode template code will have 4-space tabs hard coded, so this is a good way to fix that.

Preferred:

//1

if user.isHappy {

  // Do something

} else {

  // Do something else

}

//2

class TestDatabase: Database {

  var data: [String: CGFloat] = ["A": 1.2, "B": 3.2]

}

Not Preferred:

//1

if user.isHappy

{

  // Do something

}

else {

  // Do something else

}

//2

class TestDatabase : Database {

  var data :[String:CGFloat] = ["A" : 1.2, "B":3.2]

}

Comments

When we are needed, we can use comments to explain why a particular piece of code does something. Comments must be kept up-to-date or deleted.

We should avoid block comments inline with code, as the code should be as self-documenting as possible.

Exception: This does not apply to those comments used to generate documentation.

We should also avoid the use of C-style comments (/* … */). We can prefer the use of double- or triple-slash.

Conclusion

In this note series, we understood about iOS Best Practices and Swift Coding Standards With Code Organization, Spacing and Comments. We discussed about iOS Swift based Code Organization, Spacing and Comments concepts which will helps to ensure our code as efficient, error-free, simple ,easy maintenance enabled and bug rectification.

Thanks for reading! I hope you enjoyed and learned about Code Organization, Spacing and Comments concepts in iOS Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow other website and tutorials of iOS as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – An Overview Of Memory Safety In Swift

Hello Readers, CoolMonkTechie heartily welcomes you in this article (An Overview Of Memory Safety In Swift) .

In this article, we will learn about an overview of Memory Safety in Swift. Swift handles most memory safety automatically, to avoid conflicts. However, certain functions may cause conflicts and will either cause compile time or runtime errors. This article reviews the access conflict to memory (like In-Out Parameters, self in Methods and Properties) in swift.

A famous quote about learning is :

” One learns from books and example only that certain things can be done. Actual learning requires that you do those things.”

So Let’s begin.

Memory Safety Overview

Swift monitors risky behaviour that may occur in the code. For example, Swift ensures that variables are introduced before they’re utilized, likewise, memory isn’t accessed once its deallocated, and array indices are checked for out-of-bounds errors.

Swift also makes sure that multiple accesses to the same area of memory don’t conflict, by requiring code that modifies a location in memory to have exclusive access to that memory. Because Swift manages memory automatically, most of the time we don’t have to think about accessing memory at all. However, it’s important to understand where potential conflicts can occur, so we can avoid writing code that has conflicting access to memory. If our code does contain conflicts, we’ll get a compile-time or runtime error.

Understanding Conflicting Access to Memory

Memory access happens in our code when we do things like set the value of a variable or pass an argument to a function. For example, the following code contains both a read access and a write access:

// A write access to the memory where one is stored.
var one = 1

// A read access from the memory where one is stored.
print("We're number \(one)!")

A conflicting access to memory can occur when different parts of our code are trying to access the same location in memory at the same time. Multiple accesses to a location in memory at the same time can produce unpredictable or inconsistent behavior. In Swift, there are ways to modify a value that span several lines of code, making it possible to attempt to access a value in the middle of its own modification.

We can see a similar problem by thinking about how we update a budget that’s written on a piece of paper. Updating the budget is a two-step process: First, we add the items’ names and prices, and then we change the total amount to reflect the items currently on the list. Before and after the update, we can read any information from the budget and get a correct answer, as shown in the figure below.

Source : Swift.org – Memory Shopping

While we’re adding items to the budget, it’s in a temporary, invalid state because the total amount hasn’t been updated to reflect the newly added items. Reading the total amount during the process of adding an item gives us incorrect information.

This example also demonstrates a challenge we may encounter when fixing conflicting access to memory: There are sometimes multiple ways to fix the conflict that produce different answers, and it’s not always obvious which answer is correct. In this example, depending on whether we wanted the original total amount or the updated total amount, either $5 or $320 could be the correct answer. Before we can fix the conflicting access, we have to determine what it was intended to do.

” If we’ve written concurrent or multithreaded code, conflicting access to memory might be a familiar problem. However, the conflicting access discussed here can happen on a single thread and doesn’t involve concurrent or multithreaded code. ”

” If we have conflicting access to memory from within a single thread, Swift guarantees that we’ll get an error at either compile time or runtime. For multithreaded code, use Thread Sanitizer to help detect conflicting access across threads. “

Characteristics of Memory Access

There are three characteristics of memory access to consider in the context of conflicting access: whether the access is a read or a write, the duration of the access, and the location in memory being accessed. Specifically, a conflict occurs if we have two accesses that meet all of the following conditions:

  • At least one is a write access or a nonatomic access.
  • They access the same location in memory.
  • Their durations overlap.

The difference between a read and write access is usually obvious: a write access changes the location in memory, but a read access doesn’t. The location in memory refers to what is being accessed—for example, a variable, constant, or property. The duration of a memory access is either instantaneous or long-term.

An operation is atomic if it uses only C atomic operations; otherwise it’s nonatomic. An access is instantaneous if it’s not possible for other code to run after that access starts but before it ends. By their nature, two instantaneous accesses can’t happen at the same time. Most memory access is instantaneous. For example, all the read and write accesses in the code listing below are instantaneous:

func oneMore(than number: Int) -> Int {
    return number + 1
}

var myNumber = 1
myNumber = oneMore(than: myNumber)
print(myNumber)
// Prints "2"

However, there are several ways to access memory, called long-term accesses, that span the execution of other code. The difference between instantaneous access and long-term access is that it’s possible for other code to run after a long-term access starts but before it ends, which is called overlap. A long-term access can overlap with other long-term accesses and instantaneous accesses.

Overlapping accesses appear primarily in code that uses in-out parameters in functions and methods or mutating methods of a structure.

Conflicting Access to In-Out Parameters

In this section, we will discuss the specific kinds of Swift code that use long-term accesses. A function has long-term write access to all of its in-out parameters. The write access for an in-out parameter starts after all of the non-in-out parameters have been evaluated and lasts for the entire duration of that function call. If there are multiple in-out parameters, the write accesses start in the same order as the parameters appear.

One consequence of this long-term write access is that we can’t access the original variable that was passed as in-out, even if scoping rules and access control would otherwise permit it—any access to the original creates a conflict. For example:

var stepSize = 1

func increment(_ number: inout Int) {
    number += stepSize
}

increment(&stepSize)
// Error: conflicting accesses to stepSize

In the code above, stepSize is a global variable, and it is normally accessible from within increment(_:). However, the read access to stepSize overlaps with the write access to number.

Source : Swift.org – Memory Increment

As shown in the figure above, both number and stepSize refer to the same location in memory. The read and write accesses refer to the same memory and they overlap, producing a conflict.

One way to solve this conflict is to make an explicit copy of stepSize:

// Make an explicit copy.
var copyOfStepSize = stepSize
increment(&copyOfStepSize)

// Update the original.
stepSize = copyOfStepSize
// stepSize is now 2

When we make a copy of stepSize before calling increment(_:), it’s clear that the value of copyOfStepSize is incremented by the current step size. The read access ends before the write access starts, so there isn’t a conflict.

Another consequence of long-term write access to in-out parameters is that passing a single variable as the argument for multiple in-out parameters of the same function produces a conflict. For example:

func balance(_ x: inout Int, _ y: inout Int) {
    let sum = x + y
    x = sum / 2
    y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore)  // OK
balance(&playerOneScore, &playerOneScore)
// Error: conflicting accesses to playerOneScore

In the above code, the balance(_:_:) function modifies its two parameters to divide the total value evenly between them. Calling it with playerOneScore and playerTwoScore as arguments doesn’t produce a conflict—there are two write accesses that overlap in time, but they access different locations in memory. In contrast, passing playerOneScore as the value for both parameters produces a conflict because it tries to perform two write accesses to the same location in memory at the same time.

Because operators are functions, they can also have long-term accesses to their in-out parameters. For example, if balance(_:_:) was an operator function named <^>, writing playerOneScore <^> playerOneScore would result in the same conflict as balance(&playerOneScore, &playerOneScore).

Conflicting Access to self in Methods

A mutating method on a structure has write access to self for the duration of the method call. For example, consider a game where each player has a health amount, which decreases when taking damage, and an energy amount, which decreases when using special abilities.

struct Player {
    var name: String
    var health: Int
    var energy: Int

    static let maxHealth = 10
    mutating func restoreHealth() {
        health = Player.maxHealth
    }
}

In the restoreHealth() method above, a write access to self starts at the beginning of the method and lasts until the method returns. In this case, there’s no other code inside restoreHealth() that could have an overlapping access to the properties of a Player instance. The shareHealth(with:) method below takes another Player instance as an in-out parameter, creating the possibility of overlapping accesses.

extension Player {
    mutating func shareHealth(with teammate: inout Player) {
        balance(&teammate.health, &health)
    }
}

var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria)  // OK

In the example above, calling the shareHealth(with:) method for Oscar’s player to share health with Maria’s player doesn’t cause a conflict. There’s a write access to oscar during the method call because oscar is the value of self in a mutating method, and there’s a write access to maria for the same duration because maria was passed as an in-out parameter. As shown in the figure below, they access different locations in memory. Even though the two write accesses overlap in time, they don’t conflict.

Source : Swift.org – Memory Share Health

However, if we pass oscar as the argument to shareHealth(with:), there’s a conflict:

oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar

The mutating method needs write access to self for the duration of the method, and the in-out parameter needs write access to teammate for the same duration. Within the method, both self and teammate refer to the same location in memory—as shown in the figure below. The two write accesses refer to the same memory and they overlap, producing a conflict.

Source : Swift.org – Memory Share Health Oscar

Conflicting Access to Properties

Types like structures, tuples, and enumerations are made up of individual constituent values, such as the properties of a structure or the elements of a tuple. Because these are value types, mutating any piece of the value mutates the whole value, meaning read or write access to one of the properties requires read or write access to the whole value. For example, overlapping write accesses to the elements of a tuple produces a conflict:

var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: conflicting access to properties of playerInformation

In the example above, calling balance(_:_:) on the elements of a tuple produces a conflict because there are overlapping write accesses to playerInformation. Both playerInformation.health and playerInformation.energy are passed as in-out parameters, which means balance(_:_:) needs write access to them for the duration of the function call. In both cases, a write access to the tuple element requires a write access to the entire tuple. This means there are two write accesses to playerInformation with durations that overlap, causing a conflict.

The code below shows that the same error appears for overlapping write accesses to the properties of a structure that’s stored in a global variable.

var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy)  // Error

In practice, most access to the properties of a structure can overlap safely. For example, if the variable holly in the example above is changed to a local variable instead of a global variable, the compiler can prove that overlapping access to stored properties of the structure is safe:

func someFunction() {
    var oscar = Player(name: "Oscar", health: 10, energy: 10)
    balance(&oscar.health, &oscar.energy)  // OK
}

In the example above, Oscar’s health and energy are passed as the two in-out parameters to balance(_:_:). The compiler can prove that memory safety is preserved because the two stored properties don’t interact in any way.

The restriction against overlapping access to properties of a structure isn’t always necessary to preserve memory safety. Memory safety is the desired guarantee, but exclusive access is a stricter requirement than memory safety—which means some code preserves memory safety, even though it violates exclusive access to memory. Swift allows this memory-safe code if the compiler can prove that the nonexclusive access to memory is still safe. Specifically, it can prove that overlapping access to properties of a structure is safe if the following conditions apply:

  • We’re accessing only stored properties of an instance, not computed properties or class properties.
  • The structure is the value of a local variable, not a global variable.
  • The structure is either not captured by any closures, or it’s captured only by non-escaping closures.

If the compiler can’t prove the access is safe, it doesn’t allow the access.

That’s all about in this article.

Conclusion

In this article, we understood an overview of Memory Safety in Swift. This article reviewed the access conflict to memory (like In-Out Parameters, self in Methods and Properties) in swift.

Thanks for reading! I hope you enjoyed and learned about Memory Safety Concepts in Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow other website and tutorials of iOS as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING!!???

iOS – How To Select The Best Method Of Scheduling Background Runtime In iOS ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Select The Best Method Of Scheduling Background Runtime In iOS ?).

In this article, We will understand how to select the best method of scheduling background runtime for our app in iOS. Selecting the right strategies for our app in iOS depends on how it functions in the background.

A famous quote about Learning is :

” Change is the end result of all true learning. “


So Let’s begin.


Overview

If our app needs computing resources to complete tasks when it’s not running in the foreground, we can select from a number of strategies to obtain background runtime. Selecting the right strategies for our app depends on how it functions in the background.

Some apps perform work for a short time while in the foreground and must continue uninterrupted if they go to the background. Other apps defer that work to perform in the background at a later time or even at night while the device charges. And some apps need background processing time at varied and unpredictable times, such as when an external event or message arrives.


Different Methods Of Scheduling Background Runtime

In this section, we select one or more methods for our app based on how you schedule activity in the background.


1. Continue Foreground Work in the Background

The system may place apps in the background at any time. If our app performs critical work that must continue while it runs in the background, use beginBackgroundTask(withName:expirationHandler:) to alert the system. Consider this approach if our app needs to finish sending a message or complete saving a file.

The system grants our app a limited amount of time to perform its work once it enters the background. Don’t exceed this time, and use the expiration handler to cover the case where the time has depleted to cancel or defer the work.

Once our work completes, call endBackgroundTask(_:) before the time limit expires so that our app suspends properly. The system terminates our app if we fail to call this method.

If the task is one that takes some time, such as downloading or uploading files, use URLSession.


2. Defer Intensive Work

To preserve battery life and performance, we can schedule backgrounds tasks for periods of low activity, such as overnight when the device charges. Use this approach when our app manages heavy workloads, such as training machine learning models or performing database maintenance.

Schedule these types of background tasks using BGProcessingTask, and the system decides the best time to launch our background task.


3. Update Our App’s Content

Our app may require short bursts of background time to perform content refresh or other work; for example, our app may fetch content from the server periodically, or regularly update its internal state. In this situation, use BGAppRefreshTask by requesting BGAppRefreshTaskRequest.

The system decides the best time to launch our background task, and provides our app up to 30 seconds of background runtime. Complete our work within this time period and call setTaskCompleted(success:), or the system terminates our app. 


4. Wake Our App with a Background Push

Background pushes silently wake our app in the background. They don’t display an alert, play a sound, or badge our app’s icon. If our app obtains content from a server infrequently or at irregular intervals, use background pushes to notify our app when new content becomes available. A messaging app with a muted conversation might use a background push solution, and so might an email app that process incoming mail without alerting the user.

When sending a background push, set content-available: to 1 without alertsound, or badge. The system decides when to launch the app to download the content. To ensure our app launches, set apns-priority to 5, and apns-push-type to background.

Once the system delivers the remote notification with application(_:didReceiveRemoteNotification:fetchCompletionHandler:), our app has up to 30 seconds to complete its work. One our app performs the work, call the passed completion handler as soon as possible to conserve power. If we send background pushes more frequently than three times per hour, the system imposes rate limitations.


5. Request Background Time and Notify the User

If our app needs to perform a task in the background and show a notification to the user, use a Notification Service Extension. For example, an email app might need to notify a user after downloading a new email. Subclass UNNotificationServiceExtension and bundle the system extension with our app. Upon receiving a push notification, our service extension wakes up and obtains background runtime through didReceive(_:withContentHandler:).

When our extension completes its work, it must call the content handler with the content we want to deliver to the user. Our extension has a limited amount of time to modify the content and execute the contentHandler block.

That’s all about in this article.


Conclusion

In this article, We understood how to select the best method of scheduling background runtime in iOS.

Thanks for reading ! I hope you enjoyed and learned about selecting best method for scheduling background runtime concept in iOS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

You can find Other articles of CoolmonkTechie as below link :

You can also follow other website and tutorials of iOS as below links :

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – 5 Popular Ways Of Making Network Requests In Swift

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about five major ways of making network request in Swift. Many iOS application are clients of a REST API. This article gives an overview of common ways to accomplish tasks associated with making HTTP requests and handling responses.

A famous quote about learning is :

Change is the end result of all true learning.

So Let’s begin.

First we need to understand that how to threading relates from network requests.


How does threading relate from network requests?

In iOS much of the code that runs in your application is triggered by an event on the main event loop. The main event loop is responsible for executing code to respond to things like user interaction (e.g triggering an @IBAction) or events in a view controller’s lifecycle (e.g. viewDidLoad). Code executed from the main event loop is run on the main thread. This is convenient for us because any updates to an application’s UI elements must happen on the main thread. We’ll want to keep this rule in mind when working with network requests.

iOS provides a couple of higher level libraries for concurrent programming: Grand Central Dispatch and NSOperationQueue. We’ll be able use either to ensure us that a piece of code does or does not run on the main thread.

We should never make a synchronous network request on the main thread since this will block thread and UI will appear frozen while our request is pending. We’ll rarely run into instances where we’ll need to make synchronous requests.

When we make an asynchronous request, any of the above libraries will execute the request on a background (i.e. not the main) thread. Some methods will allow us to specify the dispatch queue on which we want the response handler to run, others will provide no guarantees. If we need to update the UI in our response handler we must ensure that the code that manipulates the UI is run on the main thread. This can be tricky because we may call into a method that calls into another method that after a long stack of calls eventually updates a UI element.

One simple way to ensure a block of code is run on the main thread using Grand Central Dispatch is as follows:

DispatchQueue.main.async {  
  // This code will be executed on the main thread
}  


Overview of popular network programming methods

There is a wide variety of ways to make HTTP requests in iOS with which we might at least want to be familiar. We will discuss the below 4 major ways of making network requests in network programming :


1. NSURLConnection

NSURLConnection is a lower level mechanism to make URL requests and is part of Apple’s Foundation Framework.

  • simplest way to make URL request.
  • provides synchronous and asynchronous requests via with completion handler blocks and delegates.
  • does not have much support for authentication or a session concept.
  • does not have an “operation” or “task” concept associated with requests so there’s no convenient way to handle queue of requests or to pause/resume.
  • does not handle parsing of common content types.
  • not much built in support for HTTP error codes / request parameters.
  • deprecated in iOS 9.


Example

Notice that we are forced to specify a operation queue on which the completion handler will run.

import UIKit

private let apiKey = "53eb9541b4374660d6f3c0001d6249ca:19:70900879"
private let resourceUrl = NSURL(string: "http://api.nytimes.com/svc/topstories/v1/home.json?api-key=\(apiKey)")!

class Story {
    var headline: String?
    var thumbnailUrl: String?

    init(jsonResult: NSDictionary) {
        ...
    }

    class func fetchStories(successCallback: ([Story]) -> Void, error: ((NSError?) -> Void)?) {
        let request = NSURLRequest(URL: resourceUrl)
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, requestError) -> Void in
            if let requestError = requestError? {
                error?(requestError)
            } else {
                if let data = data? {
                    let json = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as NSDictionary
                    if let results = json["results"] as? NSArray {
                        var stories: [Story] = []
                        for result in results as [NSDictionary] {
                            stories.append(Story(jsonResult: result))
                        }
                        successCallback(stories)
                    }
                } else {
                    // unexpected error happened
                    error?(nil)
                }
            }
        }
    }
}


2. URLSession

NSURLSession a higher level library that is part of Apple’s Foundation Framework.

  • built on top of NSURLConnection
  • better support for authentication and has a session concept
  • concept of “task” enables pausing/resuming requests
  • can perform requests while your app is in the background
  • does not handle parsing of common content types
  • not much built in support for HTTP error codes / request parameters

URLSession is now the preferred built-in method of performing network requests on iOS.


Example

class Movie {

    // ... 

    class func fetchMovies(successCallBack: @escaping (NSDictionary) -> (), errorCallBack: ((Error?) -> ())?) {
        let apiKey = "Put_Your_Client_Id_Here"
        let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)")!
        let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
        let task: URLSessionDataTask = session.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
            if let error = error {
                errorCallBack?(error)
            } else if let data = data,
                let dataDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
                //print(dataDictionary)
                successCallBack(dataDictionary)
            }
        }
        task.resume()
    }
    // ...
}


3. Codable

Codable is Apple’s latest powerful contribution to efforts to better improve the built-in networking libraries available to iOS and Mac OS engineers. Codable is actually a typealias for Encodable and Decodable protocols that allows us to quickly decode and encode external representations (such as JSON strings) as native Structs in Swift.

Before Codable was introduced to the Swift language in Swift 4, many developers had to rely on third party frameworks or building their own JSON decoding code which required a lot of boilerplate code. However, with the introduction of Codable, it’s actually really easy to write 100% Swift networking code! Let’s give it a try!


Example

Let’s assume we are implementing a movie list viewing application that retrieves a list of movies from a server to show the user, with the following JSON response.

{
    "totalFilms": 100,
    "films": [{
            "id": 11219,
            "image_url": "https://movieguru.org/sample1.png",
            "title": "The Hunt for Red October",
            "score": 4.5
        },
        {
            "id": 11169,
            "image_url": "https://movieguru.org/sample1.png",
            "title": "Wolf of Wall Street",
            "score": 5.0
        },
        {
            "id": 13671,
            "image_url": "https://movieguru.org/sample1.png",
            "title": "Superbad",
            "score": 4.2
        }
    ]
}

With the power of Codable, you can implement a native Struct object with the following code.

struct MovieResponse: Codable {
    let totalFilms: Int
    let films: [Film]
}

struct Film: Codable {
    let id: Int
    let imageURL, title: String
    let score: Double

    enum CodingKeys: String, CodingKey {
        case id
        case imageURL = "image_url"
        case title, score
    }
}

As we can see, the Struct looks almost exactly like we would want it to look if we were using it to drive a UITableViewDataSource or a custom film details View Controller.

The CodingKey is simply an enum that allows the JSONDecoder to perform an internal switch on each key of the JSON response in order to match each key to the property name of the Struct.

Can we guess why imageURL is the only case in the enum that has a declared raw value? If we’re thinking it’s related to Snake Case, we’re right! While Snake Case works in Swift, it’s not best practice, and Apple cleverly considered that an application might need properties to have different names compared to their network properties so an engineer can overwrite the property name by mapping a different variable name to each JSON parameter. If we wanted, we could make imageURL read “thumbnailURL” instead, as long as the encoding key is equal to “image_url”, the JSONDecoder will know that the JSON value for key “image_url” is set to thumbnailURL.

So how do we use it? Easy!!

Let’s go back to the example from URLSession, and instead of a general NSDictionary (which would require a lot more code on the consumption side like a MovieObject class with init(fromDict dict: NSDictionary) in order to be usable in your code base), let’s substitute it with our Codable compatible struct.

class Movie {

    // ... 

    class func fetchMovies(successCallBack: @escaping ([Film]?) -> (), errorCallBack: ((Error?) -> ())?) {
        let apiKey = "Put_Your_Client_Id_Here"
        let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)")!
        let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
        let task: URLSessionDataTask = session.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
            if let error = error {
                errorCallBack?(error)
            } else if let data = data,
                let filmResponse = try! JSONDecoder().decode(MovieResponse.self, from: data) {
                //print(filmResponse.films)
                successCallBack(filmResponse.films)
            }
        }
        task.resume()
    }
    // ...
}

It might not look like much, but a significant amount of code is saved from the Movie class object, and when we consume this API call, on the other side we’ll get the Film objects we need to drive our UI, rather than a Dictionary you’d have to iterate over, verifying each value.

Codable can save us a significant amount of time in writing networking code, and it’s growing in popularity, so we highly recommend picking it up!!


4. AFNetworking

AFNetworking is the most popular library for and is the de facto gold standard for networking tasks in the iOS world. Chances are we will want to use this library if accessing an API and making network requests is a key part of your application.

  • built on top of NSURLSession.
  • built-in support for parsing common content-types.
  • great support for common HTTP operations including handling of request params, headers, error codes.
  • great integration with UIKit components making complex behavior like loading remote images asynchronously very easy.


Example

This code starts to look a little cleaner with AFNetworking. AFNetworking does some error handling for us and gives us a way to provide a failure handler. Also note that we no longer have to parse the JSON result ourselves since AFNetworking does this automatically based on the content type. Finally note that we were able to supply our GET parameters as a Swift dictionary. This is not particularly useful here, but becomes very nice to have if there is a large number of parameters.

private let params = ["api-key": "53eb9541b4374660d6f3c0001d6249ca:19:70900879"]
private let resourceUrl = "http://api.nytimes.com/svc/topstories/v1/home.json"

class Story {
    var headline: String?
    var thumbnailUrl: String?

    init(jsonResult: NSDictionary) {
       ...
    }

    class func fetchStories(successCallback: ([Story]) -> Void, error: ((NSError?) -> Void)?) {
        let manager = AFHTTPRequestOperationManager()
        manager.GET(resourceUrl, parameters: params, success: { (operation ,responseObject) -> Void in
            if let results = responseObject["results"] as? NSArray {
                var stories: [Story] = []
                for result in results as [NSDictionary] {
                    stories.append(Story(jsonResult: result))
                }
                successCallback(stories)
            }
        }, failure: { (operation, requestError) -> Void in
            if let errorCallback = error? {
                errorCallback(requestError)
            }
        })
    }
}


5. AlamoFire

AlamoFire is another networking library by the same author as AFNetworking. It is written in Swift.

  • Swift only
  • many of the same features as AFNetworking
  • easy to use/read syntax for making common requests
  • no integration with UIKit


Example

This example demonstrates that how to use Alamofire library using Swift Code in iOS.

import UIKit
import Alamofire
class ViewController: UIViewController {
 
    @IBOutlet weak var tableView: UITableView!
    var jsonArray:NSMutableArray?
    var newArray: Array<String> = []
 
    override func viewDidLoad() {
        super.viewDidLoad()
        
        Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo") .responseJSON { response in
                print(response.request)  // original URL request
                print(response.response) // URL response
                print(response.data)     // server data
                print(response.result)   // result of response serialization
                
                if let JSON = response.result.value {
                    self.jsonArray = JSON as? NSMutableArray
                    for item in self.jsonArray! {
                        print(item["name"]!)
                        let string = item["name"]!
                        print("String is \(string!)")
                        
                        self.newArray.append(string! as! String)
                    }
                    
                    print("New array is \(self.newArray)")
                    
                    self.tableView.reloadData()
                }
        }
        
        
        
        // Do any additional setup after loading the view, typically from a nib.
    }
}

That’s all about in this article.


Conclusion

In this article, We understood about 5 Popular Ways Of Making Network Requests In Swift. We have discussed the common ways to accomplish tasks associated with making HTTP requests and handling responses in Swift.

Thanks for reading ! I hope you enjoyed and learned about the Overview of popular network programming methods in Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – How To Solve ARC Strong Reference Cycle In Swift ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about How to work Automatic Reference Counting (ARC) in Swift. We will discuss about Strong Reference Cycles problem and solution between Class Instances and for closures in Swift. Memory management is the core concept in any programming language. For more information about Memory Management Concepts, you can explore the below articles :

iOS – Why Is Advanced IOS Memory Management Valuable In Swift ?

A famous quote about learning is :

Education is not the filling of a pot but the lighting of a fire.

So Let’s begin.

Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and we do not need to think about memory management ourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.

However, in a few cases ARC requires more information about the relationships between parts of our code in order to manage memory for us. We describes those situations and shows how we enable ARC to manage all of our app’s memory. 

Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.


How To Work ARC ?

Every time we create a new instance of a class, ARC allocates a chunk of memory to store information about that instance. This memory holds information about the type of the instance, together with the values of any stored properties associated with that instance.

Additionally, when an instance is no longer needed, ARC frees up the memory used by that instance so that the memory can be used for other purposes instead. This ensures that class instances do not take up space in memory when they are no longer needed.

However, if ARC were to deallocate an instance that was still in use, it would no longer be possible to access that instance’s properties, or call that instance’s methods. Indeed, if we tried to access the instance, our app would most likely crash.

To make sure that instances don’t disappear while they are still needed, ARC tracks how many properties, constants, and variables are currently referring to each class instance. ARC will not deallocate an instance as long as at least one active reference to that instance still exists.

To make this possible, whenever we assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a “strong” reference because it keeps a firm hold on that instance, and does not allow it to be deallocated for as long as that strong reference remains.

Example :

Here’s an example of how Automatic Reference Counting works. This example starts with a simple class called Person, which defines a stored constant property called name:

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

The Person class has an initializer that sets the instance’s name property and prints a message to indicate that initialization is underway. The Person class also has a deinitializer that prints a message when an instance of the class is deallocated.

The next code snippet defines three variables of type Person?, which are used to set up multiple references to a new Person instance in subsequent code snippets. Because these variables are of an optional type (Person?, not Person), they are automatically initialized with a value of nil, and do not currently reference a Person instance.

var reference1: Person?
var reference2: Person?
var reference3: Person?

We can now create a new Person instance and assign it to one of these three variables:

reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"

Note that the message "John Appleseed is being initialized" is printed at the point that we call the Person class’s initializer. This confirms that initialization has taken place.

Because the new Person instance has been assigned to the reference1 variable, there’s now a strong reference from reference1 to the new Person instance. Because there’s at least one strong reference, ARC makes sure that this Person is kept in memory and is not deallocated.

If we assign the same Person instance to two more variables, two more strong references to that instance are established:

reference2 = reference1
reference3 = reference1

There are now three strong references to this single Person instance.

If we break two of these strong references (including the original reference) by assigning nil to two of the variables, a single strong reference remains, and the Person instance is not deallocated:

reference1 = nil
reference2 = nil

ARC does not deallocate the Person instance until the third and final strong reference is broken, at which point it’s clear that you are no longer using the Person instance:

reference3 = nil
// Prints "John Appleseed is being deinitialized"


How To Cause Strong Reference Cycles Between Class Instances ?

In the examples above, ARC is able to track the number of references to the new Person instance we create and to deallocate that Person instance when it’s no longer needed.

However, it’s possible to write code in which an instance of a class never gets to a point where it has zero strong references. This can happen if two class instances hold a strong reference to each other, such that each instance keeps the other alive. This is known as a Strong Reference Cycle.

We resolve strong reference cycles by defining some of the relationships between classes as weak or unowned references instead of as strong references. However, before we learn how to resolve a strong reference cycle, it’s useful to understand how such a cycle is caused.

Here’s an example of how a strong reference cycle can be created by accident. This example defines two classes called Person and Apartment, which model a block of apartments and its residents:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}

Every Person instance has a name property of type String and an optional apartment property that is initially nil. The apartment property is optional, because a person may not always have an apartment.

Similarly, every Apartment instance has a unit property of type String and has an optional tenant property that is initially nil. The tenant property is optional because an apartment may not always have a tenant.

Both of these classes also define a deinitializer, which prints the fact that an instance of that class is being deinitialized. This enables us to see whether instances of Person and Apartment are being deallocated as expected.

This next code snippet defines two variables of optional type called john and unit4A, which will be set to a specific Apartment and Person instance below. Both of these variables have an initial value of nil, by virtue of being optional:

var john: Person?
var unit4A: Apartment?

We can now create a specific Person instance and Apartment instance and assign these new instances to the john and unit4A variables:

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

Here’s how the strong references look after creating and assigning these two instances. The john variable now has a strong reference to the new Person instance, and the unit4A variable has a strong reference to the new Apartment instance:

We can now link the two instances together so that the person has an apartment, and the apartment has a tenant. Note that an exclamation point (!) is used to unwrap and access the instances stored inside the john and unit4A optional variables, so that the properties of those instances can be set:

john!.apartment = unit4A
unit4A!.tenant = john

Here’s how the strong references look after we link the two instances together:

Unfortunately, linking these two instances creates a strong reference cycle between them. The Person instance now has a strong reference to the Apartment instance, and the Apartment instance has a strong reference to the Person instance. Therefore, when you break the strong references held by the john and unit4A variables, the reference counts do not drop to zero, and the instances are not deallocated by ARC:

john = nil
unit4A = nil

Note that neither deinitializer was called when we set these two variables to nil. The strong reference cycle prevents the Person and Apartment instances from ever being deallocated, causing a memory leak in your app.

Here’s how the strong references look after we set the john and unit4A variables to nil:

The strong references between the Person instance and the Apartment instance remain and cannot be broken.


How To Solve Strong Reference Cycles Between Class Instances ?

Swift provides two ways to resolve strong reference cycles when we work with properties of class type: weak references and unowned references.

Weak and unowned references enable one instance in a reference cycle to refer to the other instance without keeping a strong hold on it. The instances can then refer to each other without creating a strong reference cycle.

Use a weak reference when the other instance has a shorter lifetime—that is, when the other instance can be deallocated first. In the Apartment example above, it’s appropriate for an apartment to be able to have no tenant at some point in its lifetime, and so a weak reference is an appropriate way to break the reference cycle in this case. In contrast, use an unowned reference when the other instance has the same lifetime or a longer lifetime.


Weak References

weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance. This behavior prevents the reference from becoming part of a strong reference cycle. We indicate a weak reference by placing the weak keyword before a property or variable declaration.

Because a weak reference does not keep a strong hold on the instance it refers to, it’s possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated. And, because weak references need to allow their value to be changed to nil at runtime, they are always declared as variables, rather than constants, of an optional type.

We can check for the existence of a value in the weak reference, just like any other optional value, and you will never end up with a reference to an invalid instance that no longer exists.

“Property observers aren’t called when ARC sets a weak reference to nil.”

The example below is identical to the Person and Apartment example from above, with one important difference. This time around, the Apartment type’s tenant property is declared as a weak reference:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}

The strong references from the two variables (john and unit4A) and the links between the two instances are created as before:

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

Here’s how the references look now that you’ve linked the two instances together:

The Person instance still has a strong reference to the Apartment instance, but the Apartment instance now has a weak reference to the Person instance. This means that when we break the strong reference held by the john variable by setting it to nil, there are no more strong references to the Person instance:

john = nil
// Prints "John Appleseed is being deinitialized"

Because there are no more strong references to the Person instance, it’s deallocated and the tenant property is set to nil:

The only remaining strong reference to the Apartment instance is from the unit4A variable. If we break that strong reference, there are no more strong references to the Apartment instance:

unit4A = nil
// Prints "Apartment 4A is being deinitialized"

Because there are no more strong references to the Apartment instance, it too is deallocated:

“In systems that use garbage collection, weak pointers are sometimes used to implement a simple caching mechanism because objects with no strong references are deallocated only when memory pressure triggers garbage collection. However, with ARC, values are deallocated as soon as their last strong reference is removed, making weak references unsuitable for such a purpose.”


Unowned References

Like a weak reference, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. We indicate an unowned reference by placing the unowned keyword before a property or variable declaration.

Unlike a weak reference, an unowned reference is expected to always have a value. As a result, marking a value as unowned doesn’t make it optional, and ARC never sets an unowned reference’s value to nil.

Use an unowned reference only when you are sure that the reference always refers to an instance that has not been deallocated. If we try to access the value of an unowned reference after that instance has been deallocated, we’ll get a runtime error.

The following example defines two classes, Customer and CreditCard, which model a bank customer and a possible credit card for that customer. These two classes each store an instance of the other class as a property. This relationship has the potential to create a strong reference cycle.

The relationship between Customer and CreditCard is slightly different from the relationship between Apartment and Person seen in the weak reference example above. In this data model, a customer may or may not have a credit card, but a credit card will always be associated with a customer. A CreditCard instance never outlives the Customer that it refers to. To represent this, the Customer class has an optional card property, but the CreditCard class has an unowned (and non-optional) customer property.

Furthermore, a new CreditCard instance can only be created by passing a number value and a customer instance to a custom CreditCard initializer. This ensures that a CreditCard instance always has a customer instance associated with it when the CreditCard instance is created.

Because a credit card will always have a customer, we define its customer property as an unowned reference, to avoid a strong reference cycle:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}

“The number property of the CreditCard class is defined with a type of UInt64 rather than Int, to ensure that the number property’s capacity is large enough to store a 16-digit card number on both 32-bit and 64-bit systems.”

This next code snippet defines an optional Customer variable called john, which will be used to store a reference to a specific customer. This variable has an initial value of nil, by virtue of being optional:

var john: Customer?

We can now create a Customer instance, and use it to initialize and assign a new CreditCard instance as that customer’s card property:

john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)

Here’s how the references look, now that we’ve linked the two instances:

The Customer instance now has a strong reference to the CreditCard instance, and the CreditCard instance has an unowned reference to the Customer instance.

Because of the unowned customer reference, when we break the strong reference held by the john variable, there are no more strong references to the Customer instance:

Because there are no more strong references to the Customer instance, it’s deallocated. After this happens, there are no more strong references to the CreditCard instance, and it too is deallocated:

john = nil
// Prints "John Appleseed is being deinitialized"
// Prints "Card #1234567890123456 is being deinitialized"

The final code snippet above shows that the deinitializers for the Customer instance and CreditCard instance both print their “deinitialized” messages after the john variable is set to nil.

“The examples above show how to use safe unowned references. Swift also provides unsafe unowned references for cases where you need to disable runtime safety checks—for example, for performance reasons. As with all unsafe operations, we take on the responsibility for checking that code for safety. We indicate an unsafe unowned reference by writing unowned(unsafe). If we try to access an unsafe unowned reference after the instance that it refers to is deallocated, our program will try to access the memory location where the instance used to be, which is an unsafe operation.”


Unowned Optional References

We can mark an optional reference to a class as unowned. In terms of the ARC ownership model, an unowned optional reference and a weak reference can both be used in the same contexts. The difference is that when we use an unowned optional reference, we’re responsible for making sure it always refers to a valid object or is set to nil.

Here’s an example that keeps track of the courses offered by a particular department at a school:

class Department {
    var name: String
    var courses: [Course]
    init(name: String) {
        self.name = name
        self.courses = []
    }
}

class Course {
    var name: String
    unowned var department: Department
    unowned var nextCourse: Course?
    init(name: String, in department: Department) {
        self.name = name
        self.department = department
        self.nextCourse = nil
    }
}

Department maintains a strong reference to each course that the department offers. In the ARC ownership model, a department owns its courses. Course has two unowned references, one to the department and one to the next course a student should take; a course doesn’t own either of these objects. Every course is part of some department so the department property isn’t an optional. However, because some courses don’t have a recommended follow-on course, the nextCourse property is an optional. Here’s an example of using these classes:

let department = Department(name: "Horticulture")

let intro = Course(name: "Survey of Plants", in: department)
let intermediate = Course(name: "Growing Common Herbs", in: department)
let advanced = Course(name: "Caring for Tropical Plants", in: department)

intro.nextCourse = intermediate
intermediate.nextCourse = advanced
department.courses = [intro, intermediate, advanced]

The code above creates a department and its three courses. The intro and intermediate courses both have a suggested next course stored in their nextCourse property, which maintains an unowned optional reference to the course a student should take after after completing this one.

An unowned optional reference doesn’t keep a strong hold on the instance of the class that it wraps, and so it doesn’t prevent ARC from deallocating the instance. It behaves the same as an unowned reference does under ARC, except that an unowned optional reference can be nil.

Like non-optional unowned references, we’re responsible for ensuring that nextCourse always refers to a course that hasn’t been deallocated. In this case, for example, when we delete a course from department.courses we also need to remove any references to it that other courses might have.

” The underlying type of an optional value is Optional, which is an enumeration in the Swift standard library. However, optionals are an exception to the rule that value types can’t be marked with unowned. The optional that wraps the class doesn’t use reference counting, so we don’t need to maintain a strong reference to the optional.”


Unowned References and Implicitly Unwrapped Optional Properties

The examples for weak and unowned references above cover two of the more common scenarios in which it’s necessary to break a strong reference cycle.

However, there’s a scenario, in which both properties should always have a value, and neither property should ever be nil once initialization is complete. In this scenario, it’s useful to combine an unowned property on one class with an implicitly unwrapped optional property on the other class.

This enables both properties to be accessed directly (without optional unwrapping) once initialization is complete, while still avoiding a reference cycle. This section shows you how to set up such a relationship.

The example below defines two classes, Country and City, each of which stores an instance of the other class as a property. In this data model, every country must always have a capital city, and every city must always belong to a country. To represent this, the Country class has a capitalCity property, and the City class has a country property:

class Country {
    let name: String
    var capitalCity: City!
    init(name: String, capitalName: String) {
        self.name = name
        self.capitalCity = City(name: capitalName, country: self)
    }
}

class City {
    let name: String
    unowned let country: Country
    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

To set up the interdependency between the two classes, the initializer for City takes a Country instance, and stores this instance in its country property.

The initializer for City is called from within the initializer for Country. However, the initializer for Country cannot pass self to the City initializer until a new Country instance is fully initialized, 

To cope with this requirement, we declare the capitalCity property of Country as an implicitly unwrapped optional property, indicated by the exclamation point at the end of its type annotation (City!). This means that the capitalCity property has a default value of nil, like any other optional, but can be accessed without the need to unwrap its value.

Because capitalCity has a default nil value, a new Country instance is considered fully initialized as soon as the Country instance sets its name property within its initializer. This means that the Country initializer can start to reference and pass around the implicit self property as soon as the name property is set. The Country initializer can therefore pass self as one of the parameters for the City initializer when the Country initializer is setting its own capitalCity property.

All of this means that we can create the Country and City instances in a single statement, without creating a strong reference cycle, and the capitalCity property can be accessed directly, without needing to use an exclamation point to unwrap its optional value:

var country = Country(name: "Canada", capitalName: "Ottawa")
print("\(country.name)'s capital city is called \(country.capitalCity.name)")
// Prints "Canada's capital city is called Ottawa"

In the example above, the use of an implicitly unwrapped optional means that all of the two-phase class initializer requirements are satisfied. The capitalCity property can be used and accessed like a non-optional value once initialization is complete, while still avoiding a strong reference cycle.


How To Cause Strong Reference Cycles for Closures ?

A strong reference cycle can also occur if we assign a closure to a property of a class instance, and the body of that closure captures the instance. This capture might occur because the closure’s body accesses a property of the instance, such as self.someProperty, or because the closure calls a method on the instance, such as self.someMethod(). In either case, these accesses cause the closure to “capture” self, creating a strong reference cycle.

This strong reference cycle occurs because closures, like classes, are reference types. When we assign a closure to a property, we are assigning a reference to that closure. In essence, it’s the same problem as above—two strong references are keeping each other alive. However, rather than two class instances, this time it’s a class instance and a closure that are keeping each other alive.

Swift provides an elegant solution to this problem, known as a closure capture list. However, before we learn how to break a strong reference cycle with a closure capture list, it’s useful to understand how such a cycle can be caused.

The example below shows how we can create a strong reference cycle when using a closure that references self. This example defines a class called HTMLElement, which provides a simple model for an individual element within an HTML document:

class HTMLElement {

    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }

}

The HTMLElement class defines a name property, which indicates the name of the element, such as "h1" for a heading element, "p" for a paragraph element, or "br" for a line break element. HTMLElement also defines an optional text property, which we can set to a string that represents the text to be rendered within that HTML element.

In addition to these two simple properties, the HTMLElement class defines a lazy property called asHTML. This property references a closure that combines name and text into an HTML string fragment. The asHTML property is of type () -> String, or “a function that takes no parameters, and returns a String value”.

By default, the asHTML property is assigned a closure that returns a string representation of an HTML tag. This tag contains the optional text value if it exists, or no text content if text does not exist. For a paragraph element, the closure would return "<p>some text</p>" or "<p />", depending on whether the text property equals "some text" or nil.

The asHTML property is named and used somewhat like an instance method. However, because asHTML is a closure property rather than an instance method, we can replace the default value of the asHTML property with a custom closure, if we want to change the HTML rendering for a particular HTML element.

For example, the asHTML property could be set to a closure that defaults to some text if the text property is nil, in order to prevent the representation from returning an empty HTML tag:

let heading = HTMLElement(name: "h1")
let defaultText = "some default text"
heading.asHTML = {
    return "<\(heading.name)>\(heading.text ?? defaultText)</\(heading.name)>"
}
print(heading.asHTML())
// Prints "<h1>some default text</h1>"

” The asHTML property is declared as a lazy property, because it’s only needed if and when the element actually needs to be rendered as a string value for some HTML output target. The fact that asHTML is a lazy property means that you can refer to self within the default closure, because the lazy property will not be accessed until after initialization has been completed and self is known to exist.”

The HTMLElement class provides a single initializer, which takes a name argument and (if desired) a text argument to initialize a new element. The class also defines a deinitializer, which prints a message to show when an HTMLElement instance is deallocated.

Here’s how you use the HTMLElement class to create and print a new instance:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
// Prints "<p>hello, world</p>"

” The paragraph variable above is defined as an optional HTMLElement, so that it can be set to nil below to demonstrate the presence of a strong reference cycle.”

Unfortunately, the HTMLElement class, as written above, creates a strong reference cycle between an HTMLElement instance and the closure used for its default asHTML value. Here’s how the cycle looks:

The instance’s asHTML property holds a strong reference to its closure. However, because the closure refers to self within its body (as a way to reference self.name and self.text), the closure captures self, which means that it holds a strong reference back to the HTMLElement instance. A strong reference cycle is created between the two. 

” Even though the closure refers to self multiple times, it only captures one strong reference to the HTMLElement instance.”

If we set the paragraph variable to nil and break its strong reference to the HTMLElement instance, neither the HTMLElement instance nor its closure are deallocated, because of the strong reference cycle:

paragraph = nil

Note that the message in the HTMLElement deinitializer is not printed, which shows that the HTMLElement instance is not deallocated.


How To Resolve Strong Reference Cycles for Closures ?

We resolve a strong reference cycle between a closure and a class instance by defining a capture list as part of the closure’s definition. A capture list defines the rules to use when capturing one or more reference types within the closure’s body. As with strong reference cycles between two class instances, we declare each captured reference to be a weak or unowned reference rather than a strong reference. The appropriate choice of weak or unowned depends on the relationships between the different parts of our code.

” Swift requires us to write self.someProperty or self.someMethod() (rather than just someProperty or someMethod()) whenever we refer to a member of self within a closure. This helps us remember that it’s possible to capture self by accident.”


Defining a Capture List

Each item in a capture list is a pairing of the weak or unowned keyword with a reference to a class instance (such as self) or a variable initialized with some value (such as delegate = self.delegate). These pairings are written within a pair of square braces, separated by commas.

Place the capture list before a closure’s parameter list and return type if they are provided:

lazy var someClosure = {
    [unowned self, weak delegate = self.delegate]
    (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

If a closure does not specify a parameter list or return type because they can be inferred from context, place the capture list at the very start of the closure, followed by the in keyword:

lazy var someClosure = {
    [unowned self, weak delegate = self.delegate] in
    // closure body goes here
}


Weak and Unowned References

Define a capture in a closure as an unowned reference when the closure and the instance it captures will always refer to each other, and will always be deallocated at the same time.

Conversely, define a capture as a weak reference when the captured reference may become nil at some point in the future. Weak references are always of an optional type, and automatically become nil when the instance they reference is deallocated. This enables you to check for their existence within the closure’s body.

” If the captured reference will never become nil, it should always be captured as an unowned reference, rather than a weak reference.”

An unowned reference is the appropriate capture method to use to resolve the strong reference cycle in the HTMLElement example from Strong Reference Cycles for Closures above. Here’s how we write the HTMLElement class to avoid the cycle:

class HTMLElement {

    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }

}

This implementation of HTMLElement is identical to the previous implementation, apart from the addition of a capture list within the asHTML closure. In this case, the capture list is [unowned self], which means “capture self as an unowned reference rather than a strong reference”.

We can create and print an HTMLElement instance as before:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
// Prints "<p>hello, world</p>"

Here’s how the references look with the capture list in place:

This time, the capture of self by the closure is an unowned reference, and does not keep a strong hold on the HTMLElement instance it has captured. If you set the strong reference from the paragraph variable to nil, the HTMLElement instance is deallocated, as can be seen from the printing of its deinitializer message in the example below:

paragraph = nil
// Prints "p is being deinitialized"

That’s all about in this article.


Conclusion

In this article, We understood that How to work Automatic Reference Counting (ARC) in Swift. We also discussed about Strong Reference Cycles problem and solution between Class Instances and for closures in Swift. We saw how a strong reference cycle can be created when two class instance properties hold a strong reference to each other, and how to use weak and unowned references to break these strong reference cycles.

We understood Strong Reference Cycles with different scenarios below :

  • The Person and Apartment example shows a situation where two properties, both of which are allowed to be nil, have the potential to cause a strong reference cycle. This scenario is best resolved with a weak reference.
  • The Customer and CreditCard example shows a situation where one property that is allowed to be nil and another property that cannot be nil have the potential to cause a strong reference cycle. This scenario is best resolved with an unowned reference.
  • In a third scenario, in which both properties should always have a value, and neither property should ever be nil once initialization is complete. In this scenario, it’s useful to combine an unowned property on one class with an implicitly unwrapped optional property on the other class.
  • A strong reference cycle can also occur if you assign a closure to a property of a class instance, and the body of that closure captures the instance. Swift provides an elegant solution to this problem, known as a closure capture list.

Thanks for reading ! I hope you enjoyed and learned about the Automatic Reference Counting (ARC) and Strong Reference Cycles problem and solutions with different scenarios in Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – Why Is Advanced IOS Memory Management Valuable In Swift ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about what’s beyond the basics of iOS memory management, reference counting and object life cycle. Memory management is the core concept in any programming language. Memory management in iOS was initially non-ARC (Automatic Reference Counting), where we have to retain and release the objects. Now, it supports ARC and we don’t have to retain and release the objects. Xcode takes care of the job automatically in compile time. We will explain Memory management in swift from the compiler perspective. We will discuss the fundamentals and gradually make our way to the internals of ARC and Swift Runtime, answering below questions:

  • What is Memory Management?
  • What is Memory Management Issues?
  • What is Memory Management Rules ?
  • How Swift compiler implements Automatic Reference Counting?
  • How ARC Works ?
  • How to handle Memory in ARC ?
  • How strong, weak and unowned references are implemented?
  • What is Swift Runtime ?
  • What are Side Tables?
  • What is the life cycle of Swift objects?
  • What is Reference Count Invariants during Swift object lifecycle ?

A famous quote about learning is :

An investment in knowledge pays the best interest.”

So, Let’s begin.


What is Memory Management ?

At hardware level, memory is just a long list of bytes. We organized into three virtual parts:

  • Stack, where all local variables go.
  • Global data, where static variables, constants and type metadata go.
  • Heap, where all dynamically allocated objects go. Basically, everything that has a lifetime is stored here.

We’ll continue saying ‘objects’ and ‘dynamically allocated objects’ interchangeably. These are Swift reference types and some special cases of value types.

So We can define Memory Management :

Memory Management is the process of controlling program’s memory. It is critical to understand how it works, otherwise you are likely to run across random crashes and subtle bugs.”


What is Memory Management Issues?

As per Apple documentation, the two major issues in memory management are:

  • Freeing or overwriting data that is still in use. It causes memory corruption and typically results in your application crashing, or worse, corrupted user data.
  • Not freeing data that is no longer in use causes memory leaks. When allocated memory is not freed even though it is never going to be used again, it is known as memory leak. Leaks cause your application to use ever-increasing amounts of memory, which in turn may result in poor system performance or (in iOS) your application being terminated.


What is Memory Management Rules ?

Memory Management Rules are :

  • We own the objects we create, and we have to subsequently release them when they are no longer needed.
  • Use Retain to gain ownership of an object that you did not create. You have to release these objects too when they are not needed.
  • Don’t release the objects that you don’t own.


How Swift compiler implements automatic reference counting?

Memory management is tightly connected with the concept of OwnershipOwnership is the responsibility of some piece of code to eventually cause an object to be destroyed. Any language with a concept of destruction has a concept of ownership. In some languages, like C and non-ARC Objective-C, ownership is managed explicitly by programmers. In other languages, like C++ (in part), ownership is managed by the language. Even languages with implicit memory management still have libraries with concepts of ownership, because there are other program resources besides memory, and it is important to understand what code has the responsibility to release those resources.

Swift already has an ownership system, but it’s “under the covers”: it’s an implementation detail that programmers have little ability to influence.

Automatic reference counting (ARC) is Swift ownership system, which implicitly imposes a set of conventions for managing and transferring ownership.

Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.

However, in a few cases ARC requires more information about the relationships between parts of your code in order to manage memory for you.

The name by which an object can be pointed is called a reference. Swift references have two levels of strength: strong and weak. Additionally, weak references have a flavour, called unowned.

The essence of Swift memory management is: Swift preserves an object if it is strongly referenced and deallocates it otherwise. The rest is just an implementation detail.”


How ARC Works ?

Every time you create a new instance of a class, ARC allocates a chunk of memory to store information about that instance. This memory holds information about the type of the instance, together with the values of any stored properties associated with that instance.

Additionally, when an instance is no longer needed, ARC frees up the memory used by that instance so that the memory can be used for other purposes instead. This ensures that class instances do not take up space in memory when they are no longer needed.

However, if ARC were to deallocate an instance that was still in use, it would no longer be possible to access that instance’s properties, or call that instance’s methods. Indeed, if you tried to access the instance, your app would most likely crash.

To make sure that instances don’t disappear while they are still needed, ARC tracks how many properties, constants, and variables are currently referring to each class instance. ARC will not deallocate an instance as long as at least one active reference to that instance still exists.

To make this possible, whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a “strong” reference because it keeps a firm hold on that instance, and does not allow it to be deallocated for as long as that strong reference remains.

Example :

Here’s an example of how Automatic Reference Counting works. This example starts with a simple class called Person, which defines a stored constant property called name:

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

The Person class has an initializer that sets the instance’s name property and prints a message to indicate that initialization is underway. The Person class also has a deinitializer that prints a message when an instance of the class is deallocated.

The next code snippet defines three variables of type Person?, which are used to set up multiple references to a new Person instance in subsequent code snippets. Because these variables are of an optional type (Person?, not Person), they are automatically initialized with a value of nil, and do not currently reference a Person instance.

var reference1: Person?
var reference2: Person?
var reference3: Person?

You can now create a new Person instance and assign it to one of these three variables:

reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"

Note that the message "John Appleseed is being initialized" is printed at the point that you call the Person class’s initializer. This confirms that initialization has taken place.

Because the new Person instance has been assigned to the reference1 variable, there is now a strong reference from reference1 to the new Person instance. Because there is at least one strong reference, ARC makes sure that this Person is kept in memory and is not deallocated.

If you assign the same Person instance to two more variables, two more strong references to that instance are established:

reference2 = reference1
reference3 = reference1

There are now three strong references to this single Person instance.

If you break two of these strong references (including the original reference) by assigning nil to two of the variables, a single strong reference remains, and the Person instance is not deallocated:

reference1 = nil
reference2 = nil

ARC does not deallocate the Person instance until the third and final strong reference is broken, at which point it’s clear that you are no longer using the Person instance:

reference3 = nil
// Prints "John Appleseed is being deinitialized"


How to handle Memory in ARC ?

You don’t need to use release and retain in ARC. So, all the view controller’s objects will be released when the view controller is removed. Similarly, any object’s sub-objects will be released when they are released. Note that if other classes have a strong reference to an object of a class, then the whole class won’t be released. So, it is recommended to use weak properties for delegates.


How strong, weak and unowned references are implemented?

The purpose of a strong reference is to keep an object alive. Strong referencing might result in several non-trivial problems.

  • Retain cycles. Considering that Swift language is not cycle-collecting, a reference R to an object which holds a strong reference to the object R (possibly indirectly), results in a reference cycle. We must write lots of boilerplate code to explicitly break the cycle.
  • It is not always possible to make strong references valid immediately on object construction, e.g. with delegates.

Weak references address the problem of back references. An object can be destroyed if there are weak references pointing to it. A weak reference returns nil, when an object it points to is no longer alive. This is called zeroing.

Unowned references are different flavor of weak, designed for tight validity invariants. Unowned references are non-zeroing. When trying to read a non-existent object by an unowned reference, a program will crash with assertion error. They are useful to track down and fix consistency bugs.


What is Swift Runtime ?

The mechanism of ARC is implemented in a library called Swift Runtime. It implements such core features as the runtime type system, including dynamic casting, generics, and protocol conformance registration.

Swift Runtime represents every dynamically allocated object with HeapObject struct. It contains all the pieces of data which make up an object in Swift: reference counts and type metadata.

Internally every Swift object has three reference counts: one for each kind of reference. At the SIL generation phase, swiftc compiler inserts calls to the methods swift_retain() and swift_release(), wherever it’s appropriate. This is done by intercepting initialization and destruction of HeapObjects.

Compilation is one of the steps of Xcode Build System.


What are Side Tables?

Side Tables are mechanism for implementing Swift weak references.

Typically objects don’t have any weak references, hence it is wasteful to reserve space for weak reference count in every object. This information is stored externally in side tables, so that it can be allocated only when it’s really needed.

Instead of directly pointing to an object, weak reference points to the side table, which in its turn points to the object. This solves two problems:

  • saves memory for weak reference count, until an object really needs it.
  • allows to safely zero out weak reference, since it does not directly point to an object, and no longer a subject to race conditions.

Side table is just a reference count + a pointer to an object. They are declared in Swift Runtime as follows (C++ code).

class HeapObjectSideTableEntry {
  std::atomic<HeapObject*> object;
  SideTableRefCounts refCounts;
  // Operations to increment and decrement reference counts
}


What is the life cycle of Swift objects?

Swift objects have their own life cycle, represented by a finite state machine on the figure below. Square brackets indicate a condition that triggers transition from state to state. We will discuss the finite state machines in Eliminating Degenerate View Controller States.

In live state an object is alive. Its reference counts are initialized to 1 strong, 1 unowned and 1 weak (side table starts at +1). Strong and unowned reference access work normally. Once there is a weak reference to the object, the side table is created. The weak reference points to the side table instead of the object.

From the live state, the object moves into the deiniting state once strong reference count reaches zero. The deiniting state means that deinit() is in progress. At this point strong ref operations have no effect. Weak reference reads return nil, if there is an associated side table (otherwise there are no weak refs). Unowned reads trigger assertion failure. New unowned references can still be stored. From this state, the object can take two routes:

  • A shortcut in case there no weak, unowned references and the side table. The object transitions to the dead state and is removed from memory immediately.
  • Otherwise, the object moves to deinited state.

In the deinited state deinit() has been completed and the object has outstanding unowned references (at least the initial +1). Strong and weak stores and reads cannot happen at this point. Unowned stores also cannot happen. Unowned reads trigger assertion error. The object can take two routes from here:

  • In case there are no weak references, the object can be deallocated immediately. It transitions into the dead state.
  • Otherwise, there is still a side table to be removed and the object moves into the freed state.

In the freed state the object is fully deallocated, but its side table is still alive. During this phase the weak reference count reaches zero and the side table is destroyed. The object transitions into its final state.

In the dead state there is nothing left from the object, except for the pointer to it. The pointer to the HeapObject is freed from the Heap, leaving no traces of the object in memory.


What is Reference Count Invariants during Swift object lifecycle ?

During their life cycle, the objects maintain following invariants:

  • When the strong reference count becomes zero, the object is deinitedUnowned reference reads raise assertion errors, weak reference reads become nil.
  • The unowned reference count adds +1 to the strong one, which is decremented after object’s deinit completes.
  • The weak reference count adds +1 to the unowned reference count. It is decremented after the object is freed from memory.


Conclusion

In this article, We understood about Advanced iOS Memory management in Swift. Automatic reference counting is no magic and the better we understand how it works internally, the less our code is prone to memory management errors. Here are the key points to remember:

  • Weak references point to side a table. Unowned and strong references point to an object.
  • Automatic referencing count is implemented on the compiler level. The swiftc compiler inserts calls to release and retain wherever appropriate.
  • Swift objects are not destroyed immediately. Instead, they undergo 5 phases in their life cycle: live -> deiniting -> deinited -> freed -> dead.

Thanks for reading ! I hope you enjoyed and learned about the Advanced memory management concepts in Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – Is SOLID Valuable Design Principles Applicable For Swift ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about most popular design principles SOLID in Swift. We will see that how SOLID is applicable for Swift. Now a days , a Maintainable and Reusable component is just a dream. Maybe not. SOLID principles, may be the way.

A famous quote about learning is :

Change is the end result of all true learning.

So Let’s begin.

Origin of the acronym SOLID

SOLID is an acronym named by Robert C. Martin (Uncle Bob). It represents 5 principles of object-oriented programming :

  • Single responsibility Principle
  • Open/Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

If we apply these five principles:

  • We will have flexible code, which we can easily change and that will be both reusable and maintainable.
  • The software developed will be robust, stable and scalable (we can easily add new features).
  • Together with the use of the Design Patterns, it will allow us to create software that is highly cohesive (that is, the elements of the system are closely related) and loosely coupled (the degree of dependence between elements is low).

So, SOLID can solve the main problems of a bad architecture:

  • Fragility: A change may break unexpected parts—it is very difficult to detect if you don’t have a good test coverage.
  • Immobility: A component is difficult to reuse in another project—or in multiple places of the same project—because it has too many coupled dependencies.
  • Rigidity: A change requires a lot of efforts because affects several parts of the project.

Of course, as Uncle Bob pointed out in a his article, these are not strict rules, but just guidelines to improve the quality of your architecture.

Principles will not turn a bad programmer into a good programmer. Principles have to be applied with judgement. If they are applied by rote it is just as bad as if they are not applied at all.

Principles

The Single Responsibility Principle (SRP)

According to this principle, a class should have a reason, and only one, to change. That is, a class should only have one responsibility.

Now let’s describe Single Responsibility Principle says :

THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.

Every time you create/change a class, you should ask yourself: How many responsibilities does this class have?

Let’s take a look into Swifty communication program.

import Foundation

class InterPlanetMessageReceiver {

    func receiveMessage() {
        print("Received the Message!")
    }

    func displayMessageOnGUI() {
      print("Displaying Message on Screen!")
    }
}

Now let’s understand what is Single Responsibility Principle (SRP) and how the above program doesn’t obey it.

SRP says, “Just because you can implement all the features in a single device, you shouldn’t”.

In Object Oriented terms it means: There should never be more than one reason for a class to change. It doesn’t mean you can’t have multiple methods but the only condition is that they should have one single purpose.

Why? Because it adds a lot of manageability problems for you in the long run.

Here, the InterPlanetMessageReceiver class does the following:

  • It receives the message.
  • It renders it on UI.

And, two applications are using this InterPlanetMessageReceiver class:

  • A messaging application uses this class to receive the message
  • A graphical application uses this class to draw the message on the UI

Do you think it is violating the SRP?

YES, The InterPlanetMessageReceiver class is actually performing two different things. First, it handles the messaging, and second, displaying the message on GUI. This causes some interesting problems:

  • Swifty must include the GUI into the messaging application and also while deploying the messaging application, we must include the GUI library.
  • A change to the InterPlanetMessageReceiver class for the graphical application may lead to a change, build, and test for the messaging application, and vice-versa.

Swifty got frustrated with the amount of changes it required. He thought it would be a minute job but now he has already spent hours on it. So he decided do make a change into his program and fix this dependency.

This is what Swifty came up with

import Foundation

// Handles received message
class InterPlanetMessageReceiver {

    func receive() {
        print("Received the Message!")
    }
}

// Handles the display part
class InterPlanetMessageDisplay {

    func displayMessageOnGUI() {
      print("Displaying Message on Screen!")
    }
}

Here’s how Swifty explained this:

InterPlanetMessageReceiver class will be used by the messaging application, and the InterPlanetMessageDisplay class will be used by the graphical application. We could even separate the classes into two separate files, and that will allow us not to touch the other in case a change is needed to be implemented in one.

Finally, Swifty noted down :Why we need SRP?

  • Each responsibility is an agent of change.
  • Code becomes coupled if classes have more than one responsibility.

Open/Closed Principle

According to this principle, we must be able to extend the a class without changing its behaviour. This is achieved by abstraction.

Now let’s describe Open/Closed Principle says :

SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.

If you want to create a class easy to maintain, it must have two important characteristics:

  • Open for extension: You should be able to extend or change the behaviours of a class without efforts.
  • Closed for modification: You must extend a class without changing the implementation.

Let’s see our swifty example. Swifty was quite happy with these change and later he celebrated it with a drink in Swiftzen’s best pub and there his eyes fell upon an artifact hanging on the front wall and he found all the symbols he received in the message. Quickly, he opened his diary and completed deciphering all those shapes.

Next day when he returned back, he thought why not fix the DrawGraphic class which draws only circle shape, to include the rest of the shapes and display the message correctly.

// This is the DrawGraphic
class DrawGraphic {

  func drawShape() {
     print("Circle is drawn!")
  }
}

// Updated Class code

enum Shape {
  case circle
  case rectangle
  case square
  case triangle
  case pentagon
  case semicircle
}
class circle {

}

// This is the DrawGraphic
class DrawGraphic {

  func drawShape(shape: Shape) {
     switch shape {
        case .circle:
          print("Circle is drawn")
        case .rectangle:
          print("Rectangle is drawn")
        case square:
          print("Square is drawn")
        case triangle:
          print("Triangle is drawn")
        case pentagon:
          print("Pentagon is drawn")
        case semicircle:
          print("Semicircle is drawn")
        default:
          print("Shape not provided")
     }
  }
}

Swifty was not happy with these changes, what if in future a new shape shows up, after all he saw in the artifacts that there were around 123 shapes. This class will become one fat class. Also, DrawGraphics class is used by other applications and so they also have to adapt to this change. it was nightmare for Swifty.

Open Closed Principle solves nightmare for Swifty. At the most basic level, this means, you should be able to extend a class behavior without modifying it. It’s just like I should be able to put on a dress without doing any change to my body. Imagine what would happen if for every dress I have to change my body.

After hours of thinking, Swifty came up with below implementation of DrawGraphic class.

protocol Draw {
    func draw()
}

class Circle: Draw {
    func draw() {
        print("Circle is drawn!")
    }
}

class Rectangle: Draw {
    func draw() {
        print("Rectangle is drawn!")
    }
}

class DrawGraphic {
    func drawShape(shape: Draw) {
        shape.draw()
    }
}

let circle = Circle()
let rectangle = Rectangle()
let drawGraphic = DrawGraphic()

drawGraphic.drawShape(shape: circle)  // Circle is drawn!
drawGraphic.drawShape(shape: rectangle) // Rectangle is drawn!

Since the DrawGraphic is responsible for drawing all the shapes, and because the shape design is unique to each individual shape, it seems only logical to move the drawing for each shape into its respective class.

That means the DrawGraphic still have to know about all the shapes, right? Because how does it know that the object it’s iterating over has a draw method? Sure, this could be solved with having each of the shape classes inherit from a protocol: the Draw protocol (this can be an abstract class too).

Circle and Rectangle classes holds a reference to the protocol, and the concrete DrawGraphic class implements the protocol Draw class. So, if for any reason the DrawGraphic implementation is changed, the Circle and Rectangle classes are not likely to require any change or vice-versa.

Liskov Subsitution Principle

This principle, introduced by Barbara Liskov in 1987, states that in a program any class should be able to be replaced by one of its subclasses without affecting its functioning.

Now let’s describe Liskov Substitution Principle says :

FUNCTIONS THAT USE POINTERS OR REFERENCES TO BASE CLASSES MUST BE ABLE TO USE OBJECTS OF DERIVED CLASSES WITHOUT KNOWING IT.

Inheritance may be dangerous and you should use composition over inheritance to avoid a messy codebase. Even more if you use inheritance in an improper way.

This principle can help you to use inheritance without messing it up.

Let’s see our swifty example. Swifty was implementing the SenderOrigin class to know whether the sender is from a Planet or not.

The Sender class looked something like this

Class Planet {
  func orbitAroundSun() {
  }
}

class Earth: Planet {
  func description() {
    print("It is Earth!")
  }
}

class Pluto: Planet {
  func description() {
    print("It is Pluto!")
  }
}

class Sender {
  func senderOrigin(planet: Planet) {
    planet.description()
  }
}

In the class design, Pluto should not inherit the Planet class because it is a dwarf planet, and there should be a separate class for Planet that has not cleared the neighborhood around its orbit and Pluto should inherit that.

So the principle says that Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.

Swifty whispered it is the polymorphism. Yes it is. “Inheritance” is usually described as an “is a” relationship. If a “Planet” is a “Dwarf”, then the “Planet” class should inherit the “Dwarf” class. Such “Is a” relationships are very important in class designs, but it’s easy to get carried away and end up with a wrong design and a bad inheritance.

The “Liskov’s Substitution Principle” is just a way of ensuring that inheritance is used correctly.

In the above case, both Earth and Pluto can orbit around the Sun but Pluto is not a planet. It has not cleared the neighborhood around its orbit. Swifty understood this and changed the program.

class Planet {
    func oribitAroundSun() {
        print("This planet Orbit around Sun!")
    }
}

class Earth: Planet {
    func description() {
        print("Earth")
    }
}

class DwarfPlanet: Planet {
    func notClearedNeighbourhoodOrbit() {

    }
}

class Pluto: DwarfPlanet {
  func description() {
        print("Pluto")
    }
}

class Sender {
    func senderOrigin(from: Planet) {
        from.description()
    }
}

let pluto = Pluto()
let earth = Earth()

let sender = Sender()
sender.senderOrigin(from: pluto) // Pluto
sender.senderOrigin(from: earth) // Earth

Here, Pluto inherited the planet but added the notClearedNeigbourhood method which distinguishes a dwarf and regular planet.

  • If LSP is not maintained, class hierarchies would be a mess, and if a subclass instance was passed as parameter to methods, strange behavior might occur.
  • If LSP is not maintained, unit tests for the base classes would never succeed for the subclass.

Swifty can design objects and apply LSP as a verification tool to test the hierarchy whether inheritance is properly done.

Interface Segregation Principle

The Principle of segregation of the interface indicates that it is better to have different interfaces (protocols) that are specific to each client, than to have a general interface. In addition, it indicates that a client would not have to implement methods that he does not use.

Now let’s describe Interface Segragation Principle says :

CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.

This principle introduces one of the problems of object-oriented programming: the fat interface.

An interface is called “fat” when has too many members/methods, which are not cohesive and contains more information than we really want. This problem can affect both classes and protocols.

Let’s continue our swifty example. Swifty was quite astonished with the improvement in his program. All the changes were making more sense. Now, it was time to share this code with different planet. Swiftzen 50% GDP was dependent on selling softwares and many planet has requested and signed MOU for the Inter Planet communication system.

Swifty was ready to sell the program and but he was not satisfied with current client interface. Let’s us look into it.

protocol interPlanetCommunication {
  func switchOnAntenna()
  func setAntennaAngle()
  func transmitMessage()
  func receivedMessage()
  func displayMessageOnGUI()
}

Now for anyone who want to use interPlanetCommunication, he has to implement all the five methods even-though they might not required.

So the principle says that Many client-specific interfaces are better than one general purpose interface. The principle ensures that Interfaces are developed so that each of them have their own responsibility and thus they are specific, easily understandable, and re-usable.

Swifty quickly made changes to his program interface:

protocol antenna {
  func switchOnAntenna()
  func setAntennaAngle()
}

protocol message {
  func transmitMessage()
  func receivedMessage()
}

protocol dispaly {
  func displayMessageOnGUI()
}

Dependency Inversion Principle

According to the Dependency inversion principle:

“HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.”

“ABSTRACTIONS SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTIONS.”

This principle tries to reduce the dependencies between modules, and thus achieve a lower coupling between classes.

This principle is the right one to follow if you believe in reusable components.

DIP is very similar to Open-Closed Principle: the approach to use, to have a clean architecture, is decoupling the dependencies. You can achieve it thanks to abstract layers.

Let’s continue our swifty example. Before finally shipping the program to all the clients, Swifty was trying to fix the password reminder class which looks like this.

class PasswordReminder {
  func connectToDatabase(db: SwiftZenDB) {
    print("Database Connected to SwiftzenDB")
  }

  func sendReminder() {
    print("Send Reminder")
  }
}

PasswordReminder class is dependent on a lower level module i.e. database connection. Now, let suppose that you want to change the database connection from Swiftzen to Objective-Czen, you will have to edit the PasswordReminder class.

Finally the last principle states that Entities must depend on abstractions not on concretions.

To fix above program Swifty made these changes:

protocol DBConnection {
  func connection()
}

class SwiftzenDB: DBConnection {
  func connection() {
    print("Connected to SwiftzenDB")
  }
}

class PasswordReminder {
  func connectToDatabase(db: DBConnection) {
    db.connection()
  }

  func sendReminder() {
    print("Send Reminder")
  }
}

The DBConnection protocol has a connection method and the SwiftzenDB class implements this protocol, also instead of directly type-hinting SwiftzenDB class in PasswordReminder, Swifty instead type-hint the protocol and no matter the type of database your application uses, the PasswordReminder class can easily connect to the database without any problems and OCP is not violated.

The point is rather than directly depending on the SwiftzenDB, the passwordReminder depends on the abstraction of some specification of Database so that if any the Database conforms to the abstraction, it can be connection with the PasswordReminder and it will work.

That’s all about in this article.

Conclusion

In this article, We understood about SOLID principles in Swift. We learnt that how SOLID is application for Swift. If we follow SOLID principles judiciously, we can increase the quality of our code. Moreover, our components can become more maintainable and reusable.

The mastering of these principles is not the last step to become a perfect developer, actually, it’s just the beginning. We will have to deal with different problems in our projects, understand the best approach and, finally, check if we are breaking some principles.

We have 3 enemies to defeat: Fragility, Immobility and Rigidity. SOLID principles are our weapons. We tried to explain the SOLID concepts in Swift easy way with examples.

Thanks for reading ! I hope you enjoyed and learned about SOLID Principles in Swift. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !!???

iOS – Understanding KVO In Swift

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, We will learn about KVO in Swift. KVO, which stands for Key-Value Observing, is one of the techniques for observing the program state changes available in Objective-C and Swift. This article demonstrates the KVO importance in Objective-C and Swift with practical example.

A famous quote about learning is :

” One learns from books and example only that certain things can be done. Actual learning requires that you do those things.”

So Let’s begin.


Overview

The KVO concept is simple:

” When we have an object with some instance variables, KVO allows other objects to establish surveillance on changes for any of those instance variables. “

KVO is a practical example of the Observer pattern. What makes Objective-C (and Obj-C bridged Swift) unique is that every instance variable that you add to the class becomes observable through KVO right away!

But in the majority of other programming languages, such a tool doesn’t come out of the box – we usually need to write additional code in the variable’s setter to notify the observers about the value changes.

Swift has inherited KVO from Objective-C, so for a full picture we need to understand how KVO works in Objective-C.


KVO in Objective-C

Consider we have a class named Person with properties name and age

@interface Person: NSObject
 
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
 
@end

The objects of this class now are able to communicate the changes of the properties through KVO, but with no additional code – this feature comes for free !

So the only thing we need to do is to start the observation in another class:

@implementation SomeOtherClass

- (void)observeChanges:(Person *)person {
    [person addObserver:self
             forKeyPath:@"age"
                options:NSKeyValueObservingOptionNew
                context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context {
    if ([keyPath isEqualToString:@"age"]) {
        NSNumber *ageNumber = change[NSKeyValueChangeNewKey];
        NSInteger age = [ageNumber integerValue];
        NSLog(@"New age is: %@", age);
    }
}

@end

That’s it! Now every time the age property changes on the Person we’ll have New age is: ... printed to the log from the observer’s side.

As we can see, there are two methods involved in KVO communication.

The first is addObserver:forKeyPath:options:context:, which can be called on any NSObject, including Person. This method attaches the observer to an object.

The second is observeValueForKeyPath:ofObject:change:context: which is another standard method in NSObject that we have to override in our observer’s class. This method is used for handling the observation notifications.

There is a third method, removeObserver:forKeyPath:context:, which allows us to stop the observation. It’s important to unsubscribe from notifications if the observed object outlives the observer. So the subscription just has to be removed in the observer’s dealloc method.

Now, let’s talk about the parameters of the methods used in KVO.

- (void)addObserver:(NSObject *)observer 
         forKeyPath:(NSString *)keyPath
            options:(NSKeyValueObservingOptions)options
            context:(nullable void *)context;

Here, The method have the following parameters:

  • observer is the object that will be receiving the change notifications. Usually, we provide self in this parameter, as the addObserver: is called from inside own instance method.
  • keyPath is a string parameter that in simplest case is just the name of the property we want to observe. If the property references a complex object hierarchy it can be a set of property names for digging into that hierarchy: "person.father.age"
  • options is an enum that allows for customizing what information is delivered with notification and when it should be sent. Available options are NSKeyValueObservingOptionNew and NSKeyValueObservingOptionOld, which control whether to include the most recent and the previous values respectively. There is also NSKeyValueObservingOptionInitial for triggering the notification right after the subscription, and NSKeyValueObservingOptionPrior for diffing the changes in a collection, such as insertions of deletions in NSArray.
  • context is a reference to object of an arbitrary class, which can be helpful for identifying the subscription in certain complex use cases, such as when working with CoreData. In most other cases we simply provide nil here.

The method we used for handling the update notifications

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context

Here, The method have the following parameters :

  • keyPath is the same string value we provided when attaching the observer. We may ask why it is provided here as well. The reason is that we may be observing multiple properties at once, so this parameter can be used to distinguish the notifications for one property from another.
  • object is the observed object. Since we can observe changes on more than one object, this parameter allows us to identify who’s property has changed.
  • change is the dictionary with information about the changed value. Based on the NSKeyValueObservingOptions we provided upon subscription, this dictionary may contain the current value under key NSKeyValueChangeNewKey, previous value for NSKeyValueChangeOldKey, and the “diff” information when observing changes in a collection: NSKeyValueChangeIndexesKey and NSKeyValueChangeKindKey
  • context is the reference provided upon subscription. Again, used for proper observation identification and in most cases can be ignored.


When KVO does not work

Even though KVO looks like magic, there is nothing extraordinary behind it. In fact, we can have direct access to its internals, which are hidden by default.

The trick is how Objective-C generates setter for properties. When we declare a property like

@property (nonatomic, assign) NSInteger age;

The factual setter generated by Objective-C is equivalent to the following:

- (void)setAge:(NSInteger)age {
    [self willChangeValueForKey:@"age"];
    _age = age;
    [self didChangeValueForKey:@"age"];
}

And if we explicitly define the setter without calling these willChangeValueForKey and didChangeValueForKey.

- (void)setAge:(NSInteger)age {
    _age = age;
}

… the KVO will stop working for this property.

So basically, these two methods willChangeValueForKey and didChangeValueForKey allow KVO to deliver the updates to the subscribers, and the developer can opt-out by omitting those calls from the setter.

It is important to understand that every @property synthesised by Objective-C adds a hidden instance variable with _ prefix.

For example, @property NSInteger age; generates an instance variable with the name _age that can be accessed just like the property:

self.age = 25;
self._age = 25;

The difference is that self.age = 25; triggers setter setAge:, while self._age = 25; changes the stored variable directly.

This means that even if the KVO is enabled for the age property, the KVO communication will work correctly for self.age = 25; and won’t deliver an update for self._age = 25;

Another way to break free from KVO is to not use @property in the first place, but instead store the instance variable in the anonymous category of the class:

@interface Person () {
    NSInteger _privateVariable;
}
@end

For such variables, Objective-C does not generate setter and getter, thus not enabling KVO.


KVO in Swift

Swift has inherited the support for the KVO from Objective-C, but unlike the latter, KVO is disabled in Swift classes by default.

Objective-C classes used in Swift keep KVO enabled, but for a Swift class we need to set the base class to NSObject plus add @objc dynamic attributes to the variables:

class Person: NSObject {
    @objc dynamic var age: Int
    @objc dynamic var name: String
}

There are two APIs available in Swift for Key-Value Observing: the old one, which came from Objective-C, and the new one, which is more flexible, safe and Swift-friendly.

Let’s start with the new one:

class PersonObserver {

    var kvoToken: NSKeyValueObservation?
    
    func observe(person: Person) {
        kvoToken = person.observe(\.age, options: .new) { (person, change) in
            guard let age = change.new else { return }
            print("New age is: \(age)")
        }
    }
    
    deinit {
        kvoToken?.invalidate()
    }
}

As we can see, the new API is using a closure callback for delivering the change notification right in the place where the subscription started.

This is more convenient and safe because we no longer need to check the keyPathobject or context, – no other notifications are delivered in that closure, just the one we’ve subscribed on.

There is a new way for managing the observation lifetime – the act of subscribing returns a token of type NSKeyValueObservation which has to be stored somewhere, for example, in an instance variable of the observer class.

Later on, we can call invalidate() on that token to stop the observation, like in the deinit method above.

The final change is related to the keyPath. String was error-prone because when we rename a variable the compiler won’t be able to tell us that the keyPath now leads to nowhere. Instead, this new API is using Swift’s special type for keyPath, which allows the compiler to verify the path is valid.

The options parameter has just the same set of options as in Objective-C. If we need to provide more than one option, we just bundle them in an array: options: [.new, .old]

The old API is also available, although it maintained all its disadvantages, so we encourage you to use the new API instead.

Here is the old one:

class PersonObserver: NSObject {
    
    func observe(person: Person) {
        person.addObserver(self, forKeyPath: "age",
                           options: .new, context: nil)
    }
    
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        if keyPath == "age",
           let age = change?[.newKey] {
             print("New age is: \(age)")
        }
    }
}

The old API requires the observer to be an NSObject descendant as well. We also need to verify the keyPathobject, and context, since other notifications are also delivered in this method, just like in Objective-C.

That’s all about in this article.


Conclusion

In this article, We understood about KVO in Swift. This article described about the KVO importance in Objective-C and Swift with practical example.

Thanks for reading ! I hope you enjoyed and learned about the KVO Concepts in iOS. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING!!???

Exit mobile version