Pages

Sunday 29 June 2014

Programming in Swift [Basic]

Swift is a new programming language introduce by Apple at WWDC 2014. This language supports iOS7+ and you can integrate Swift with Objective-C and vice versa. 

I am covering Swift in three parts: Basic, Intermediate, and Advance.  This post is all about basic of Swift Programming language. 

Its a brand new language and to learn this you don't require prior knowledge of Objective-C, but basics knowledge of C programming and Object Oriented Programming required. To execute Swift code you need latest version of development IDE (Xcode 6).


Playground

      We are going to use new document type ".playground" to experiment with Swift. Its supported by Xcode 6. Playground allow you to write/edit the swift code and see the result immediately side by side. 

Xcode create a playground for cocoa by default, you can create iOS playground through File --> New --> File --> iOS/Source/Playground. Cheers!! now you have a playground to play with Swift. Playground comes with some default code, it saying Hello playground, now delete the line starting with var keyword, We will discuss var latter in this tutorial. 

As usual say "Hello" to playground by printing a string. 



    println("Hello Playground")


Can you  see the "Hello Playground" message in right pan? No right!! Okay so to see the result, you need to open the console output pan (View --> Assistant Editor --> Show Assistant Editor). In third pan you can see the "Hello Playground" message. Okay! so what is the use of second pan? It shows value of variables and expressions. So whatever you print or draw comes under console pan.


Constants & Variables

      You can use "let" keyword to create constants and "var" keyword to create variables. I have created two variables below :


    //constant 
    let minimumPrice = 18.5//Double type

    //Variables
    var myVariable = 42 // Inter type
    var blogName = "Coding for Bugs" //String type


You have just created one constant as "minimumPrice" and two variables: "myVariable" is of type Integer and "blogName" is of type String. Wait we have not given any type, how swift is deciding the type of variable? Okay so swift infer the type of variable from its value. So as soon as you assign any variable a number, its become Int. If you assign string its become string, and so on...

Swift is a type safe language, that means you can't assign a int value to a String variable. So once type is infer you can't change the type of variable by assigning another type of value. If you will do so, It will be reported as compile time error.

As you know Swift infer the type itself but you can also give the desire type to a variable or constant at time of declaration, this is known as Type Annotation. For example lets create one Double and String variable. 



    var price: Double = 13.0 //Swift infer floating number to Double by default

    var helloMessage: String = "Hello reader"


The colon(:) in declaration means of type so that above declaration can be read as: 
    Declare a variable called price that is of type Double.
    Declare a variable called helloMessage that is of type String.

Semicolons

      “Unlike many other languages, Swift does not require you to write a semicolon (;) after each statement in your code, although you can do so if you wish.”

Data types in Swift

  • Int Its used for whole numbers. Ex: var num: Int = 32
  • Float Its used for numbers with decimal points. Ex: var fNum: Float = 32.1
  • Double Its used for bigger numbers with decimal points. Ex: var dNum = 32.6374
  • String Its used for ordered sequences of characters. Ex: var pi = "π",
       var name: String = "you name"
  • Bool Its used for true or false. Ex: var isRead: Bool = false
  • Array Its used for collection of same type data. Ex: let array = String[]()
  • Dictionary Its used for collection of same type data and key.         Ex: let emptyDictionary = Dictionary<String, Float>()
  • Tuple Its used for collection of objects of any type. Use () to create tuple.
         
    Ex: var HTTP404Error = (404, "Not Found")

Tuples

      Tuples group multiple values into a single compound value. The values in tuples an be of any types and don't have to be of the same type. This is the primary difference between Array and Tuples.


    // 1. Creating tuple
    let http404Error = (404, "Not Found") //type is (Int, String), and equals (404, "Not Found")”

    // 2. Accessing elements of tuple
    let (statusCode, statusMessage) = http404Error
    println("The status code is \(statusCode)") //String interpolation: use \() to insert any value in string
    println("The status message is \(statusMessage)")

    // 3. Ignoring any element in tuple, Use underscore "_" to ignore any value
    let (justTheStatusCode, _) = http404Error
    println("The status code is \(justTheStatusCode)")

    //4. Accessing individual element values in tuple using index number
    println("The status code is \(http404Error.0)")
    println("The status message is \(http404Error.1)")

    // 5. Naming individual elements in a tuple when tuple defined
    let http200Status = (statusCode: 200, description: "OK")
    println("The status code is \(http200Status.statusCode)")
    println("The status message is \(http200Status.description)")


In above code we have created two tuples named as http404Error and http200Status.and in other parts we have used first tuple in different ways. 

1. The (404, "Not Found") tuple groups together an Int and a String to give the HTTP status code two separate values: a number and a human-readable description. It can be described as “a tuple of type (Int, String)”.

2. We have decompose tuple in different constant named as status code and status message. We have inserted value of those constant in string using String Interpolation.

3. We have used _ to ignore second element "status message" of tuple. 

4. We have use elements index number to access their value. Index start from 0.

5. We have given names to individual elements of tuple. These name helps us in accessing individual elements. 

NOTE: don't forget to see the log by opening console(opt + cmd + enter)


String Interpolation

      Its include the name of a constant or variable as a placeholder in a longer string, and to prompt Swift to replace it with the current value of that constant or variable. Wrap the name in parentheses and escape it with a backslash before the opening parenthesis. Ex. println("The status message is \(statusMessage)")

Optionals

      Optionals variable either contains a value or does not contain any value at all. For example lets say you have a string value and you are trying to convert it to number/ Int. It not possible that every string can be converted into an integer. Thats why swift toInt method of String class return an optional value. 

    let possibleNumber = "123"
    let convertedNumber = possibleNumber.toInt()


Because the toInt method might fail, it returns an optional Int, rather than an Int. An optional Int is written as Int?, not Int. The question mark indicates that the value it contains is optional, meaning that it might contain some Int value, or it might contain no value at all.

If you will try to print or use a optional value directly then it might lead to a crash because it might be nil. It means no value. Swift nil is different from Objective-C nil. In case of Objective-C its a pointer to nil but in Swift nil is not a pointer. Simply it is the absence of a value of a certain type. 

Note: Optional of any type can be set to nil not only Object type.

Unwrapping Values of optionals:    
     You can use an if statement to find out whether an optional contains a value. If an optional does have a value, it evaluates to true; if it has no value at all, it evaluates to false.

Once you’re sure that the optional does contain a value, you can access its underlying value by adding an exclamation mark (!) to the end of the optional’s name. The exclamation mark effectively says, “I know that this optional definitely has a value; please use it.” This is known as forced unwrapping of the optional’s value:



    if convertedNumber {
        println("\(possibleNumber) has an integer value of \(convertedNumber!)")
    } else {
        println("\(possibleNumber) could not be converted to an integer")
    }


If you try to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

Using if else each time is boring and time consuming So swift has introduce a new concept call Optional binding, that we can use to Unwrap the value. Optional Binding is used to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable. Optional binding can be used with if and while statements to check for a value inside an optional, and to extract that value into a constant or variable, as part of a single action.



    if let actualNumber = possibleNumber.toInt() {
        println("\(possibleNumber) has an integer value of \(actualNumber)")
    } else {
        println("\(possibleNumber) could not be converted to an integer")
    }
    // prints "123 has an integer value of 123


It will execute else part when it is not possible to convert the given string into a number. 

Operators

      Swift supports all Objective-C operators where some of them are modified and others same as objective-C. Its also support operator overloading that we will discuss in Advance tutorial of this series. 

All arithmetic operator are same as C except reminder operator (%). Now reminder operator work with floating point and negative number. Ex: 8 % 2.5   // equals 0.5 and -9 % 4   // equals -1 

Increment, decrement, unary minus, logical, and compound assignment operator as same as C. 

Swift supports all C based comparison operator and also introduced two new comparison operator (=== and !==). Which you use to test whether two object references both refer to the same object instance.

Range Operator 
   Swift includes two range operators, which are shortcuts for expressing a range of values:

  1. Closed Range Operator(a...b)
         The  closed range operator (
    a...b) defines a range of values that runs from a to b, and include a and b.
  2. Half-Closed Range operator(a..<b)
        Half-closed range operator (
    a..<b) define a range of values thats run from a to b but does not include b. Thats why its called half-closed range. See the below example: 


    for index in 1...5 {
        //here index is of type Int. No need to write var before index
        println("\(index) times 5 is \(index * 5)")
    }
    // 1 times 5 is 5
    // 2 times 5 is 10
    // 3 times 5 is 15
    // 4 times 5 is 20
    // 5 times 5 is 25

    //If you change above range to Half-Closed(1..<5) then it will only up to 20.



Control Flow

      Swift supports all control flow statement of Objective-C with a huge modification in Switch statement. Its also change the way we write conditions, Now we don't need to write brackets () around the condition you can directly write the condition followed by flower braces {}. Examples:



    // If else  conditions
    var a = 2
    var b = 6
    if a > b {
        println("Yes!! \(a) is not greater than \(b)")
    } else {
        println("No!! \(a) is greater than \(b)")
    }

    //while loop 
    while a != b {
        a += 2
        println("a incremented to \(a)")
    }



Switch Statement
      In swift switch statement has below changes 
  • No need to write break statement. Swift is smart enough to break out of matched case.
  • Body of each case must contain at least one executable statement. to ignore any case use break statement.
  • Multiple matching can be separated by comma. Ex: case 2,3,4: .
  • Switch value can be matched against any built in type: Int, Double, String, Tuple, Range.
  • switch statement must be exhaustive. Using default case is easy way to get rid of this condition. 


    let count = 3_000_000_000_000 //you can use _ in number to make it redable
    let countedThings = "stars in the Milky Way"
    var naturalCount: String
    switch count {
    case 0,1:
        naturalCount = "very few"
    case 2...3:
        naturalCount = "a few"
    case 4...9:
        naturalCount = "several"
    case 10...99:
        naturalCount = "tens of"
    case 100...999:
        naturalCount = "hundreds of"
    case 1000...999_999:
        naturalCount = "thousands of"
    default:
        naturalCount = "millions and millions of"
    }
    println("There are \(naturalCount) \(countedThings).")
    // prints "There are millions and millions of stars in the Milky Way.


In above example we are matching a number and commenting about number of stars. In case first we are trying to match multiple values against some value to switch. In rest of conditions we we are trying to match switch value against range of value. 

Without the default statement this switch will not become exhaustive  because its not matching all possible value of count. Thats means every possible value of the type being considered must be matched by one of the switch case.

Switch and Tuple: We can also use tuple to test multiple value in switch statement. You can also bind the elements of tuple to variable or constant. See below example:



    let somePoint = (1, 1)
    var comment:String

    switch somePoint {
    case (0, 0):
        comment = ("(0, 0) is at the origin")
    case (_, 0):
        comment = ("(\(somePoint.0), 0) is on the x-axis")
    case (0, _):
        comment = ("(0, \(somePoint.1)) is on the y-axis")
    case (-2...2, -2...2):
        comment = ("(\(somePoint.0), \(somePoint.1)) is inside the box")
    case (let x, let y):
        ("(\(x), \(y)) is outside of the box")
    }


Above code will print "(1, 1) is inside the box" and in above switch statement we have not used default statement, because without that our switch statement is . If you wish to use default you can replace case (let x, let y) by default statement and replace x and y with indexes of individual elements. 

Thats it, in basic. In next part we will discuss Collections, Functions, Class, Closures etc.
Thanks for reading!! Please do not forget to leave your valuable comments. Bye Bye !!