Swift 3: Beyond the first look


Version:

Run the command to know the Swift version you are using,

~$ xcrun swift -version
Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
Target: x86_64-apple-macosx10.9
~$

Variable

Swift is a type-safe language. It can infer data type from default value provided.

Each variable need an initial value OR have to be declared with a type.

var aStringVariable = "Hello world"
var anotherStringVariable: String
var anIntVariable: Int                  // 64-bit signed integer
var anInt8Variable: Int8                // 8-bit signed integer
var anInt16Variable: Int16              // 16-bit signed integer
var anInt32Variable: Int32              // 32-bit signed integer
var anInt64Variable: Int64              // 64-bit signed integer
var anUnsignedIntVariable: UInt         // 64-bit unsigned integer
var anUnsignedInt8Variable: UInt8       // 8-bit unsigned integer
var anUnsignedInt16Variable: UInt16     // 16-bit unsigned integer
var anUnsignedInt32Variable: UInt32     // 32-bit unsigned integer
var anUnsignedInt64Variable: UInt64     // 64-bit unsigned integer
var aDoubleVariable: Double
var aFloatVariable: Float
var aBooleanVariable: Bool
var aCharacterVariable: Character

Some interesting notes:

  • Character can be double quoted in Swift. If not defined explicitly, it will be inferred as String, var myChar : Character = "a"
  • Boolean can’t be assigned to zero or one but true/false

Check variable type,

var lightSwitchOn: Bool = true
var dimmer: Int = 7
var dimmerWithDecimals: Float = 3.14
var veryPreciseDimmer: Double = 3.14159265359

// check variable type 
print(type(of: lightSwitchOn))
print(type(of: veryPreciseDimmer))

In general, there is no syntactical differences between Float and Double, but Double isn’t always better; use Float where speed is more important than accuracy.

var pi: Float = 3.14159265359
var pi2: Double = 3.14159265359

print(pi) // 3.14159
print(pi2) // 3.14159265359

Constant

Constant starts with ‘let’ keyword in Swift. Using ‘let’ is highly recommended whenever possible. Besides type safety there are some internal performance optimization by Swift compiler.

Literal vs Constants
A literal is a value that is written exactly as it’s meant to be interpreted. In contrast, a variable is a name that can represent different values during the execution of the program. And a constant is a name that represents the same value throughout a program. But a literal is not a name — it is the value itself.
Source:
http://stackoverflow.com/questions/485119/what-does-the-word-literal-mean

String

Declare String,

let aString = String()
let anotherString = ""

Swift string class is built from Unicode scalar values you can type emoji directly into string literals. To popup the emoji keyboard in Xcode playground, type control + command + space

let similarTruth = "💰can't buy me 💖"
let similarAnimal = "🐙"

Print all the characters in a String

var anotherString = "Hello"
for character in anotherString.characters {
    print (character)
}

Notice that String doesn’t have any length property

let aString = "Hello World"
print(theTruth.characters.count)

Reverse a String

var simpleString = "Hola"
var reversedString = simpleString.characters.reversed()
// Here, reversedString is a ReversedCollection<String.CharacterView>
// So you can not just write print(reversedString). Instead,

for character in reversedString {
    print (character)
}

String interpolation,

var name = "Kate"
var customizedBirthdayCheer = "Happy Birthday, \(name)!"

Finding a substring within a string,

var word = "fortunate"
word.contains("tuna")

Replacing a substring,

var password = "Mary had a little loris"
var newPassword = password.replacingOccurrences(of: "a", with: "A")

Conditional statement

  • Curly braces are REQUIRED, even if there is a single statement.
  • Parenthesis are not needed around the condition.
  • Pre/ Post -increment/ decrement are deprecated and will be removed in Swift 3.

If-else condition

let x = 5

if x < 5 {
    print("x < 5") } else if x == 5 {     print("x == 5") } else {     print ("x >= 5")
}

While loop

var index = 0
let x = 5

while index < x {
    index += 1      // index++ is deprecated
}

For loop

for i in 0 ... 10 { // for (var i = 0; i <= 10; i++ )
    print("i = \(i)")
}

for i in 0 ..< 10 { // for (var i = 0; i < 10; i++ )
    print("i = \(i) and i * i = \(i * i)")
}

Do while loop

var index = 0
let x = 5

repeat {
    index += 1
} while index < x

Optional basics

  • Variable/constant has to be intialized before used. Otherwise, compile error
  • Optional variable/constant can have a value OR it will be ‘nil’
  • Optional variable/constant is strongly typed too. Either contain a valid value or ‘nil’
  • Opitonal variable/constant can be set to ‘nil’ explicitely
  • Optional variable/constant need to be unwrapped before use. Before unwrap you need to be sure it has a value.
var optionalString: String?
var optionalInt: Int?

if optionalInt != nil {
    var anIntVariable = optionalInt! // unwrapping
    print (anIntVariable)
}

// OR

if let anIntVariable = optionalInt {
    // execution will be here iff optinalInt != nil
    print(anIntVariable) // by default unwrapped
} else {
    print("optionalInt is nil")
}

Function

Function with parameter and return type,

func calculateTip(priceOfMeal: Double) -> Double {
    return priceOfMeal * 0.15
}

let priceOfMeal = 43.27

let tip = calculateTip(priceOfMeal: priceOfMeal)

Function params are by default constant.

func placeFirstLetterLast(_ myString: String) -> String {
    var myString = myString
    myString.append(firstCharacter(of: myString))
    myString.remove(at: myString.startIndex)
    return myString
}

On calling a function, you need to specify the name of all variable as key:value (except the first one)

func foo() {
    // no params, no return type
}

func boo() -> String {
    return ""
    // no params, String return type
}

func coo(first: String) -> String {
    return first
    // one String param, String return type
}

func doo(first: String, second: Int) -> Int {
    return second
    // one String param, one Int param, Int return type
}

func moo(first: String, second: Int, third: Int = 2) -> Int {
    return third
    // Default param third set to 2
}

func koo(first: String) {
    // first = "Haha" // Error: params are constant
    // var first: String will make it a varaible
}

foo()
boo()
coo("Haha")
doo("Haha", second: 5) // Error: doo("Haha, 5)
moo("Haha", second: 5) // omit the default param
moo("Haha", second: 5, third: 3) // default param value

Chain function,

func addExcitementToString(string: String) -> String {
    return string + "!"
}

// chained together twice
let excitedString = addExcitementToString(string: addExcitementToString(string: "yay"))

// chained together 4 times
let reallyExcitedString = addExcitementToString(string: addExcitementToString(string: addExcitementToString(string: addExcitementToString(string: "wahoo"))))

External and Local Parameter Names,

// Prints out a string
func reverseAndPrint(_ string: String) {
    var reversedString = ""
    for character in string.characters {
        reversedString = "\(character)" + reversedString
    }
    print(reversedString)
}

// Takes a named parameter.
// forwardString - External parameter name 
// string - Local parameter name 
func reverseAndPrint(forwardString string: String) {
    var reversedString = ""
    for character in string.characters {
        reversedString = "\(character)" + reversedString
    }
    print(reversedString)
}

reverseAndPrint("regal")
reverseAndPrint(forwardString:"time")

If no external parameter name is needed then we can use _

Pure Functions
A pure function is a function that only operates on the values it receives, and that returns a new value.

A huge benefit of pure functions is that they are easier to understand and easier to reuse because a pure function has no effect on any existing object in the app. Instead, a pure function generates something new: a return value. We can easily integrate pure functions into any app without worrying if they will affect existing objects.

Class

  • Instance variable need to initialized with default value OR the class need to have a constructor
  • Constructor is a special function with name ‘init’
  • Current instance reference is ‘self’
class Person {
    var firstName: String = "Sherlock"
    var lastName: String = "Holms"
    var age: Int

    init() {
        // Constructor
        self.age = 50
    }

    // Method
    func getDescription() -> String {
        return "FirstName: \(self.firstName) and LastName: \(self.lastName) and Age: \(self.age)"
    }
}

var p = Person()    // Creating object
print("FirstName: \(p.firstName)")
print(p.getDescription())

instanceof OR is of type

class Person {
    var firstName: String = "Sherlock"
    var lastName: String = "Holms"
}

class Student: Person {
    var id: String = "0123456789"
}

var s = Student()

if s is Person {
    print("s is a Person too")

    var p = s as Person // casting to Person
    print(p.firstName)

} else {
    print ("This will not be executed")
}

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.