Skip to content

5. IOS Development 1

1 All you need to know about iOS development career

  • With the growing popularity of iPhones, iPads and iPods and the appetite for new apps, we can expect a steady demand for iOS developers who can work some magic when it comes to developing apps.
  • Home automation and Health are the two industries that are witnessing a lot of demand. Other industries like Travel, Transportation, Retail, Insurance, Banking and Financial Markets, Energy and Utilities, Telco and Law Enforcement are just some of the sectors that require iOS Developers.
  • The average salary for iOS professionals is 68% higher than the average salary for other job postings. Indeed reports that the iOS professionals draw about 98,000 USD per annum (ranges from 105K-155K by other sources).
  • Job titles: Mobile App Developer, Mobile Architect, iOS Developer ..etc.
  • What you need to learn: Objective C, IOS, Swift, XCode, Interface Builder, Version Control, Frameworks.

2 The 100 days of swift

  • String interpolation: print("Hello, \(name)!") the \(name) is the interpolation where name is a variable.
  • Use let to make a constant and var to make a variable.
  • Type annotations: var str: String = "Hello, playground" where : String is the type annotation.
  • Swift is type safe, which means that it won’t let you mix types. For example, you can’t add an integer to a string.
  • Multi-line strings: var str = """ This \n is a multi-line \n string """
  • Arrays: var array = [1, 2, 3, 4, 5]
  • Sets: var set = Set(["a", "b", "c"])
  • Tuples:
    • var tuple = (first: "Taylor", last: "Swift"), tuple.0 or tuple.first to access the first element.
    • Tuples are fixed in size, you can’t add or remove items from a tuple; but you can change the values inside it.
  • Dictionaries:
    • var dict = [ "name": "Taylor", "city": "London", "age": 25 ]
    • dict["unknown"] = nil to remove an item.
    • dict["someKey"], // nil
    • dict["someKey", default: "Unknown"] // “Unknown”
  • Empty Collections:
    • var emptyArray = [Int]()
    • var emptySet = Set<String>()
    • var emptyDict = [String: Float]()
    • var emptyArray = Array<Int>()
    • var emptyDict = Dictionary<String, Float>()
  • Enumerations, or enums for short: enum Result { case success case failure }
  • Conditional statements:
    • if condition { // code } else if condition { // code } else { // code }
    • switch condition { case value: // code default: // code }
    • and: &&, or: ||, not: !
    • Ternary operator: condition ? true : false
  • Range operators:
    • ..< excludes the upper bound, ... includes the upper bound.
    • for i in 1..<5 { print(i) } // 1, 2, 3, 4
    • for i in 1...5 { print(i) } // 1, 2, 3, 4, 5
  • Loops:
    • for i in 1...10 { print(i) }
    • let count = 1 ...10; for n in count { print(n) } or for el in array { print(el) }
    • while condition { // code }
    • repeat { // code } while condition, similar to do-while in C.
    • Use break to exit a loop, and continue to skip the current item and continue to the next one.
    • You can name loops: outerLoop: for i in 1...10 { innerLoop: for j in 1...5 {} }, and then use the loop name after break or continue to exit or continue that loop.
    • Exiting or continuing the outer loop will affects its inner loops.
  • Functions:
    • func functionName(arg: Type) -> ReturnType { return value }
    • Labels: func functionName(externalName arg: Type) -> ReturnType { return value }, then you can call the function like this: functionName(externalName: arg).
    • You can omit the external label such as func functionName(_ arg: Type) -> ReturnType { return value }, then you can call the function like this: functionName(arg).
    • Default values: func functionName(arg: Type = defaultValue) -> ReturnType { return value }
    • Variadic functions: func functionName(arg: Type...) -> ReturnType { return value }, then you can call the function like this: functionName(arg1, arg2, arg3).
    • Checked exceptions: func functionName(arg: Type) throws -> ReturnType { throw "error" return value }
    • do, try, catch:
      • do { try functionName(arg) } catch { print(error) }
      • do { try functionName(arg) } catch let error as ErrorType { print(error) }
      • do { try functionName(arg) } catch let error as ErrorType where condition { print(error) }
    • inout parameters: func functionName(arg: inout Type) -> ReturnType { return value }, then you can call the function like this: functionName(&arg). The & is required before the argument name where you pass the reference of the variable.
  • Closure: This section from this source is confusing; let’s read the other sources.

3 The swift programming language swift 5.7

Basics

  • Assertions:
    • Only in debug mode, assert(condition, message), if the condition is false, the message is printed and the app is terminated.
  • Preconditions:
    • Checked in both debug and production mode.
    • Can be disabled in production mode using -Ounchecked compiler flag.
    • precondition(condition, message), if the condition is false, the message is printed and the app is terminated.
  • Assertions and Preconditions can not be caught by catch blocks; they just terminate the app.

var x = 0.0, y = 0.0, z = 0.0 // multiple variables in one line
typealias AudioSample = UInt16 // type alias

// tuples
let http404Error = (404, "Not Found") // tuple
let (statusCode, statusMessage) = http404Error // decompose tuple

// optional
var optionalInt: Int? = 404 // optional
optionalInt = nil // optionals can hold `nil` or a value, you must address nil case when you use it
if (optionalInt != nil) {
    print(optionalInt!) // force unwrap, can cause runtime error if the optional is nil
}

// optional binding
if let actualNumber = Int(possibleNumber) { // optional binding
    print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else { // if the optional is nil, the else block is executed
    print("\"\(possibleNumber)\" could not be converted to an integer")
}

// Error handling
func canThrowAnError() throws {
    // this function may or may not throw an error
}

do {
    try canThrowAnError()
    // no error was thrown
} catch ErrorType1 {
    // an error of type ErrorType1 was thrown
} catch ErrorType2 where condition {
    // an error of type ErrorType2 was thrown
} catch {
    // an error was thrown, but it is not ErrorType1 nor ErrorType2
}

// assertions
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")

// preconditions
precondition(index > 0, "Index must be greater than zero.")

Basic Operators

  • Prefix operators: appear before the operand, such as !b(Urinary prefix operator, Negation).
  • Postfix operators: appear after the operand, such as a! (Urinary postfix operator, Optional Unwrapping).
  • Infix operators: appear between two operands, such as a + b (Binary infix operator, Addition) or a ? b : c (Ternary infix operator, Conditional).
// ternary conditional operator
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
/* equals to */ let rowHeight = contentHeight + if hasHeader { 50 } else { 20 }

// nil-coalescing operator
let defaultColorName = "red"
var userDefinedColorName: String? // defaults to nil
var colorNameToUse = userDefinedColorName ?? defaultColorName

// range operators
for i in 1...5 {} // closed range operator, 1, 2, 3, 4, 5
for i in 1..<5 {} // half-open range operator, 1, 2, 3, 4
for i in 1... {} // one-sided range operator, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
for i in arr[...5] {} // one-sided range operator, ..., 3, 4, 5: loop through the first 6 elements of array
for i in arr[5...] {} // one-sided range operator, 5, 6, 7, 8, 9, ...: start from the 6th element of array till the end
for i in arr[..<5] {} // one-sided range operator, 0, 1, 2, 3, 4: loop through the first 5 elements of array

Strings and Characters

// loop through string characters
for character in "Dog!🐶" {
    print(character) // type: Character
}

// unicode
let s = "\u{24}" // $, unicode scalar U+0024
let s = "\u{2665}" // ♥, unicode scalar U+2665
let s = "\u{1F496}" // 💖, unicode scalar U+1F496
let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}" // 🇺🇸, unicode scalar U+1F1FA U+1F1F8

// string indices
var s ="This is a string";
s.count // 16
s.isEmpty // false
s.startIndex // 0
s.endIndex // 16
s[s.startIndex] // "T"
s[s.index(before: s.endIndex)] // "g"
s[s.index(after: s.startIndex)] // "h"
s[s.index(s.startIndex, offsetBy: 4)] // " "

// inserting and removing
s.append(" 🐶") // "This is a string 🐶"
s.insert("!", at: s.endIndex) // "This is a string 🐶!"
s.remove(at: s.index(before: s.endIndex)) // "This is a string 🐶"
s.removeSubrange(s.index(s.endIndex, offsetBy: -2)..<s.endIndex) // "This is a string"
s.hasPrefix("This") // true
s.hasSuffix("string") // true
s.lowercased() // "this is a string"
s.uppercased() // "THIS IS A STRING"

Collection Types

  • Collection types are mutable if the variable is declared with var and immutable if the variable is declared with let.
  • Can NOT enter values with different types into a collection.
  • Ordered: Array, Range, String. Unordered: Set, Dictionary.
  • Arrays:
let arr = [1, 2, 3] // type: Array<Int>, immutable
var arr = [1, 2, 3] // type: Array<Int>, mutable
var arr: [Int] = [1, 2, 3] // type: Array<Int>, mutable
var arr = Array<Int>() // type: Array<Int>, mutable
var zArr = Array(repeating: 0, count: 3) // [0, 0, 0]
var arrConcatenate = zArr + [4, 5, 6] // [0, 0, 0, 4, 5, 6]
arr.count // 3
arr.isEmpty // false
arr.append(4) // [1, 2, 3, 4]
arr += [5] // [1, 2, 3, 4, 5]
arr.insert(0, at: 0) // [0, 1, 2, 3, 4, 5]
arr.remove(at: 0) // [1, 2, 3, 4, 5]
arr.removeLast() // [1, 2, 3, 4]
arr.removeFirst() // [2, 3, 4]
arr.removeFirst(2) // [4]
arr.removeSubrange(0..<1) // []

// iterating over an array
for item in arr { print(item) }
for (index, item) in arr.enumerated() { print("\(index): \(item)") }
  • Sets:
    • Sets hash every element in the set, so the elements must be hashable.
    • All equal elements has the same hash value, thus they go into the same position in the set, and no duplicates.
    • If the element is not hash-able, it can not be put into a set.
let set: Set<Int> = [1, 2, 3] // type: Set<Int>, immutable
var set: Set<Int> = [1, 2, 3] // type: Set<Int>, mutable
var set = Set<Int>() // type: Set<Int>, mutable
set.count // 3
set.isEmpty // false
set.insert(4) // [1, 2, 3, 4]
set.remove(4) // [1, 2, 3]
set.contains(1) // true
set.contains(4) // false

// iterating over a set
for item in set { print(item) }

// set operations
let set1: Set<Int> = [1, 2, 3]
let set2: Set<Int> = [3, 4, 5]
set1.intersection(set2) // [3]
set1.union(set2) // [1, 2, 3, 4, 5]
set1.subtracting(set2) // [1, 2]
set1.symmetricDifference(set2) // [1, 2, 4, 5]
set1 == set2 // false, all elements are the same
set1.isSubset(of: set2) // false, all elements in set1 are in set2
set1.isSuperset(of: set2) // false, all elements in set2 are in set1
set1.isStrictSubset(of: set2) // false, all elements in set1 are in set2, and set1 != set2
set1.isStrictSuperset(of: set2) // false, all elements in set2 are in set1, and set1 != set2
set1.isDisjoint(with: set2) // false, set1 and set2 have at least one element in common
  • Dictionaries:
let dict = ["a": 1, "b": 2, "c": 3] // type: Dictionary<String, Int>, immutable
var dict = ["a": 1, "b": 2, "c": 3] // type: Dictionary<String, Int>, mutable
var dict: [String: Int] = ["a": 1, "b": 2, "c": 3] // type: Dictionary<String, Int>, mutable
var dict = Dictionary<String, Int>() // type: Dictionary<String, Int>, mutable
dict.count // 3
dict.isEmpty // false
dict["d"] = 4 // ["a": 1, "b": 2, "c": 3, "d": 4]
dict["d"] = 5 // ["a": 1, "b": 2, "c": 3, "d": 5]
dict.updateValue(6, forKey: "d") // ["a": 1, "b": 2, "c": 3, "d": 6]
dict["d"] = nil // ["a": 1, "b": 2, "c": 3], remove the key-value pair
dict.removeValue(forKey: "c") // ["a": 1, "b": 2], remove the key-value pair
dict["a"] // 1
dict["e"] // nil
dict["e", default: 0] // 0, if the key does not exist, return the default value
dict.keys // ["a", "b"]
dict.values // [1, 2]

// iterating over a dictionary
for (key, value) in dict { print("\(key): \(value)") }
for key in dict.keys { print(key) }
for value in dict.values { print(value) }

Control Flow

// fallthrough
let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough // fallthrough to the next case
default:
    description += " an integer."
}
print(description) // The number 5 is a prime number, and also an integer.

// defer
func processFile(filename: String) throws {
    if exists(filename) {
        let file = open(filename)
        defer {
            close(file)
        }
        while let line = try file.readline() {
            // Work with the file.
        }
        // close(file) is called here, at the end of the scope.
    }
}


// availability
if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}

// guard
let number = Int("123")
guard let number = number else {
    // if number is nil, execute this block
    return
}

// available + guard
guard #available(iOS 10, macOS 10.12, *) else {
    // Fall back to earlier iOS and macOS APIs
    return
}

Functions

  • Functions are self-contained chunks of code that perform a specific task. Swift supports no parameters, named parameters, labeled parameters, default parameters, in-out parameters, nested functions.
  • Parameters are named and typed values that functions accept as input when they are called. Swift passes parameters by value by default, unless you specify in-out parameters.
  • Functions can also return a value of a specified type. If the function does not return a value, its return type is Void. Void return type can be omitted from the function declaration.
  • Both parameters and return values are optional.


4 5 XCode

  • XCode is an IDE for developing iOS apps.
  • Run Xcode on windows:
    • Hire a Mac in the cloud: Use services like MacStadium, MacInCloud, or XCodeClub.
    • virtual machine: Use VMWare or VirtualBox to run macOS on your Windows PC.
    • Hackintosh: Modify your PC to run macOS.
    • Build using cross-platform frameworks: Use cross-platform frameworks to generate the ios App. like React Native, Flutter, Xamarin, Appcelerator, PhoneGap, etc.

References


  1. Gopinath, S. (2019, May 22). All you need to know about iOS development career. Edureka. https://www.edureka.co/blog/ios-development-career 

  2. The 100 days of swift. (n.d.). Hacking with Swift. https://www.hackingwithswift.com/100 

  3. The swift programming language swift 5.7. (n.d.). Apple Inc. https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html 

  4. XCode. (n.d.). Apple Developer. https://developer.apple.com/documentation/xcode 

  5. XCode for windows (12 ways to build iOS apps on PC). (2019, May 9). CodeWithChris. https://codewithchris.com/xcode-for-windows/