swift

home

contents

Swift version on my Mac

Variable Type from Assignment Statment

Declare a variable - var, let

    var s: String
    s = "hello"
    s = "hello again"  // if you use let, not var, it means a constant. 
            

function - passing parameter - one parameter name

                                                 
     func myFunction(p: String){                // parameter name: type
        print("p = \(p)")              // parameter name for both func definition and its usage.
     }

            myFunction(p: "Spring time in Blue Hill, Massachusetts in 2017")  // parameter name: value object
            

function - passing parameter - two parameter names

    func myFunction(myFirstDogName d: String){
        print("my first dog name is \(d)")
    }

            myFunction(myFirstDogName: "Tairo")
            

function - passing parameter - no external parameter name

    func myFunction(_ d: String){
        print("my second dog name is \(d)")
    }

            myFunction("Emi")
            
    // your code
    var contents = ["part 1" : "intro", "part 2" : "Swift Optional"]
    contents.updateValue("Swift type", forKey: "part 2")   // forKey is a external parameter
    contents
    // method definition in Swift standard library
    func updateValue(_ value: Value, forKey key: Key)
            

You can test the above 3 experiments, using the same overloading function name, myFunction.

class - init, properties, methods, class inheritance

When a func is in class, It is a method, not function.

    // code snippet for this demo
    class Employee {
        let firstName: String
        let lastName: String
    
        init(firstName: String, lastName: String){
            self.firstName = firstName
            self.lastName = lastName
        }
    
        func introSelf(greeting: String) -> String{
            let message = greeting + firstName
            return message
        }
    }

    let employee1 = Employee(firstName: "Peter", lastName: "Kao")
    employee1.introSelf(greeting: "My name is ")
            

Optional

background
    //  not optional
    // After you instantiate a class Dog object with its dog name

    class Dog{
        dogName: String = "Tairo"
    }
    let dog1 = Dog()
    print(dog1.dogName)            // You see Tairo

    // Forced Optional  !
    // The object is possilby not created, the value is nil.
    // for technical reason, I am certain, it is created.
    // one example is the a ui label created from XCode as below:

    // @IBOutlet weak var label: UILabel!
    
    class Dog{
        dogName: String! = "Tairo"
    }
    let dog1 = Dog()
    print(dog1.dogName!)            // You see Tairo, the same, with ! or without !    
        

Optional

    //   1. define two classes
    class EmployeeDescription{
        var short: String
        var long: String?
        var extraLong: String?
        init(p_short: String){
            self.short = p_short
        }
    }

    class Employee{
        var empName: String
        var homePhoneNo: String?
        var description: EmployeeDescription?
        var address: String?
    
        init(p_empName: String){
            self.empName = p_empName
            //self.description = p_desc
        }
    }

    //   2.1  create class EmployeeDescription, and set one property
    var emp1Desc = EmployeeDescription(p_short: "Peter likes Swift language.")
    emp1Desc.long = "Peter has two dogs."

    //   2.2  test
    emp1Desc.short
    emp1Desc.long
    emp1Desc.extraLong

    //   3.1 create class Employee, and set two optional properties
    var emp1 = Employee(p_empName: "Peter")
    emp1.homePhoneNo = "111-222-3333"
    emp1.description = emp1Desc


    //   3.2 test
    emp1.empName
    emp1.homePhoneNo
    emp1.address
    emp1.description?.short
    emp1.description?.long
    emp1.description?.extraLong

    //    4.  test and extract the data at one assignment statement
    //        if the value is nil, return false
    //        then, the code must responds accordingly
    if let temp1 = emp1.address{
        temp1
    } else {
        print("address is nil")                    // output nil
    }

    if let temp2 = emp1.homePhoneNo{
        print(temp2)                               // output 111-222-3333
    } else {
        print("homePhoneNo is nil")
    }

    if let temp3 = emp1.description?.long{
        print(temp3)
    }else{
        print("long desciption is nil")            // output Peter has two dogs
    }

    if let temp4 = emp1.description?.extraLong{
        print(temp4)
    }else{
        print("extra long desciption is nil")      // output nil
    }

            

Summary

more code snippets

    // 1. print wrapped object
    let s: Int?     // decare this is optional
    s = 50          // assign a value to create an object
    print(s)        // print an unwrapped object,  Optional(50),
    print(s!)       // forced unwrapping, the outpust is 50 

    // 2. In this demo, the optional operators  ?, ! are on object values, not type.
    var w: String? = "hello"
    print(w)                      // Optional("hello")
    var uw = w!
    print(uw)                     // hello
    var w2: String? = uw
    print(w2)                     // Optional("hello")

    // 3. relation is "HAS", not inheritace.
    If there is a chain for classes, the relationship is not inheritance.
    Like the previous exampe, class Employee may has a class EmployeeDescription or not.
            

Any, cast, optional casts

    //  1. setup the lab
    class Dog{
        let name: String
        init(name: String){
            self.name = name
        }
    }
    class Puppy: Dog{
        var hobby: String
        init(para: String, hobby: String){
            self.hobby = hobby
            super.init(name: para)
        }
    }

    var dog = Dog(name: "Emi")
    dog.name         // Emi
    var puppy = Puppy(para: "Tairo", hobby: "play")
    puppy.name        // Tairo
    puppy.hobby       // play

    puppy is Puppy    // true
    puppy is Dog      // true

    //   2.   up cast
    let up1 = puppy as Dog         // up cast,  no optional operator needed, always ok
    let up2 = puppy as AnyObject   // up cast
    let up3 = puppy as Any         // up cast

    //   3.1 down cast - optional, unsuccessful cast
    //let down1 = obj1 as? Puppy
    if let down1 = dog as? Puppy {
        print("the puppy is \(down1)")
    }else{
        print("cast fail, it is not a puppy")            // cast fails, it is not a puppy
    }

    //   3.2. down cast - forced optional
    //  let down2 = dog as! Puppy                       app crash if forced cast

    //   3.3  down cast - optional, success cast
    //        There are many reasons for up cast, maybe from some libraries.
    //        Here,  the demo is limited for technical point.
    var arr: [Any] = [111, 9.99, "hello", puppy]
    if let down2 = arr[3] as? Puppy {
        print("the puppy's hobby is \(down2.hobby)")      // the puppy's hobby is play
    }else{
        print("cast fail, it is not a puppy")
    }
            

down cast example in ios

Any example in ios

function - passing parameter - closure

Like Javascript, you can pass function parameter with function. It is called closure.

    let names = ["Tairo", "Emi", "Joy", "Wiwi", "Buddy", "Tiger"]
    let namesPrefixT = names.filter({(dog: String) -> Bool in
        return dog.characters.count < 5
    })
    print(namesPrefixT)      // ["Emi", "Joy", "Wiwi]
           

* dog is one item in the array.
description of Array's method, filter
Returns an array containing, in order, the elements of the sequence that satisfy the given predicate. In this example, filter is used to include only names shorter than five characters.

REST service request example

    ....
    let session = URLSession(configuration: config)
    let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
                       // the closure is the callback to handle data from the service...
                 })
    // note: the task is executed asynchronously, not in UI thread
            

Description for URLSession's method dataTask:
Creates a task that retrieves the contents of a URL based on the specified URL request object, and calls a handler upon completion.

closure with short hand syntax

The syntax can be complex, I just copy sample code skeleton. One example is listed as below:

    let names = ["Tairo", "Emi", "Joy", "Wiwi", "Buddy", "Tiger"]

    let sNames = names.sorted{$0 < $1}
    print(sNames)         // ["Buddy", "Emi", "Joy", "Tairo", "Tiger", "Wiwi"]

    let rsNames = names.sorted{$0 > $1}
    print (rsNames)       // ["Wiwi", "Tiger", "Tairo", "Joy", "Emi", "Buddy"]
            
    // function argument using closure
    names.forEach {dogName in
        print(dogName)            // output dog name per line
    }
    // for in Swift language construct
    for dogName in names{
        print(dogName)            // output dog name per line
    }
            

Generic

// --- demo 1 --- var myArray = Array<Any>() // colllection type - Array myArray.append("apple") myArray.append(3) myArray.append(24.55) // --- demo 2 --- var myDogs = Array<String>() myDogs.append("Tairo") myDogs.append("Emi") // --- demo 3 --- class MyDog<T,U>{ var dogName: T var dogAge: U init(dogName: T, dogAge: U){ self.dogName = dogName self.dogAge = dogAge } } let dog1 = MyDog<String, Int>(dogName: "Emi", dogAge: 7) let dog2 = MyDog<String, Double>(dogName: "Tairo", dogAge: 7.5) dog1.dogAge dog2.dogAge

Tuple

    import Foundation   // needed for JSONSerialization
    func createTuple() -> (String, Int){
        //step 1,  simulate get a json data from a REST service,
        //         and populate it into a JSON object in Swift
        let jsonObject: [String: Any] = [
            "name": "Tairo",
            "weight": 30
        ]
        let validJSON = JSONSerialization.isValidJSONObject(jsonObject)    //true

        //step 2, extract the json data
        let name = jsonObject["name"]
        let weight = jsonObject["weight"]
    
        // step 3, create a tuple, and return it
        return (name as! String, weight as! Int)
    }

    func useTuple(){
        let (name2, weight2) = createTuple()   // no collection name for the tuple is needed
        print("name2 = \(name2)")              // output   Tairo
        print("weight2 = \(weight2)")          // output   30
    }

    useTuple()
            

Dictionary

    //  Dictionary example
    var dog: [String: Any]    //key type: value type
    dog = ["name": "Tairo", "weight": 30]
    dog["name"]
    dog["weight"]


    //  Array of Distionary, like sql row data
    var dogs : [[String: Any]]
    dogs = [["name": "Tairo", "weight": 30],["name": "Emi", "weight": 29] ]

    dogs[0]["name"]
    dogs[0]["weight"]
    dogs[1]["name"]
    dogs[1]["weight"]

    // note: Both array and dictionary use [], their usages and meanings are different.
            

Protocal, Delegate