Posts

Showing posts from March, 2018

Swift Basics: Formatting guide

Do not use semi-colons. Do not use () for if else statement - if x < 5 {} instead of if (x<5){} Types should always start with a capital letter. They should not have underscore. MyClass Functions and methods should be named in camel case. Constants and variables should be named in camel case. Use the default indentations given. Add an extra blank line between functions and methods.  Use triple /// in block comments for functions.  Use double // in comments for inline comments.  Define everything as a constant first, then change it to a variable when you have to change it.  Only use optional types when necessary. Avoid forced unwrapping. Use optional binding instead. Use type inference: instead of var a: Int = 1, use var a = 1 Use shorthand declarations for collections: var myArray: [String] = [] instead of var myArray: Array<String> Use switch case instead of multiple if statements.

Swift Basics: Concurrency and Parallelism - running multiple tasks

Concurrency - many tasks starting, running, and completing at the same time period. Parallelism - 2 or more tasks running simultaneously. If we have a 4-core processor, we can run 4 tasks simultaneously. Asynchronous functions are functions that run in the background. These functions might take a long time to complete. It starts with the long task running and comes back before the task's completion. To have asynchronous running of tasks, we can make use of GCD and operation queues. GCD stands for Grand Central Dispatch. There are three types of queues that it uses. Serial queue - executed in the order in which they are submitted. No two tasks will run simultaneously. Concurrent queue - execute concurrently, but start according to the time they are added to the queue. Main dispatch queues - main thread. With dispatch queues, threads are managed efficiently and we can control the order in which they start. Let's say I have a function called Countdown(timing: Int).

Swift Basics: Mix and Match

Mix and Match is when you want to combine other codes with Swift programming. For instance, using objective C with swift programming. You can find more details here.

Swift Basics: Closures

Closures are when you add functions, etc, blocks of code to a variable declaration. It can take in parameters and can have return values. Here is a simple closure: let c1 = { (name: String) -> Void in print(name) } To execute it: c1("ABC") They are self contained blocks of code. They can be used throughout the application code. We can indicate that a closure is a parameter in a function. func test(handler: (String) -> Void) { //(String) -> Void means that it is a closure that takes in a String and does not have a return value   handler("efg") } Then when we call the function: test(handler: c1) With a return value: let c2 = {   (name: String) -> String in   return "Well \(name)" } to call it: var message = c2("Mary") Let's say we have a function that accepts a closure as a parameter: func test(handler:() -> Void) {   handler() } create a closure: let c3 = { ()-> Void in print("ABC

Swift Basics - Generics

We use generics when we need to create functions that can be used with multiple types. If I wish to create a function that swaps 2 objects, I will need to create a function for each type, without generics: func swapInt(a: Int, b: Int){} func swapString(a: String, b: String){} func swapDouble(a: Double, b: Double){} We can condense all 3 into one function that makes use of a generic type: func swap<T>(a: T, b: T){} T is the generic type assigned. You can also choose another name for T: func swap<XYZ>(a: XYZ, b: XYZ) If there are multiple types, we can use different name placeholders for the types: func swap<T, E>(a: T, b: E){} To call the function: var a = 5 var b = 10 swap(a: &a, b: &b) //placing & before a and b just ensures that their values get updated and persists outside of the function A generic type is a class, structure or enumeration that can work with any type. We can create a class of a generic type: class Listing<G>{  var items = [G]()  f

Swift Basics - subscripts

Shortcuts to access elements in collections, lists or sequences. Subscript of an array: var array1 = [1, 2, 3, 4, 5, 6] print(array1[2]) Custom subscripts: class MyFoods {  private var foods = ["Ice cream", "Pizza", "Hot dog"]  subscript(index: Int) -> String  {  get { return names[index]}  set { names[index] = newValue} } To use it: var myFoods = MyFoods() print(myFoods[0]) Ready only custom subscripts: class MyFoods {  private var foods = ["Ice cream", "Pizza", "Hot dog"]  subscript(index: Int) -> String  {  get { return names[index]} } OR class MyFoods {  private var foods = ["Ice cream", "Pizza", "Hot dog"]  subscript(index: Int) -> String  {   return names[index] } You can calculate something inside a subscript: struct AreaOfTable {  var length: Int  subscript(index: Int) -> Int  { return length * Index} } To use: var myTable = AreaOfTable(length: 3) print(myTable[3]) A subscript

Swift basics - Extensions

Extensions: When you need to edit a type like string without overriding existing functionality: extension String {   var firstLetter: Characters?{ get return self.characters.first}}  func reverse() -> String{//... } } To call it: var myString = "ABC" print(myString.firstLetter)

Swift basics - classes and structures

Classes and structures Classes and structures have properties, methods, initialisers, subscripts (provide access to values), and extensions. Difference between classes and structures: A class can inherit from parent classes, a structure is unable to. Structures can implement protocols, though. Structures do not have custom deinitialisers, classes do. If a class object gets sent to a a function, changes to the object will persist. However, changes to the structure will not persist. Structures or classes? Structures make use of less memory overheads, so there are performance gains in using them. To create a class: class MyClass {    //properties    let a = 3    //or let a: Int    var b = "" } Create a structure: struct MyStruct{    //properties    let a = 3    var b = "" } You can able to create an instance of a class and of a structure: var aStruct = MyStruct() var aClass = MyClass() By default, you can give the properties in the structure a value during instantiatio

Swift basics - functions

Defining a function with parameters and return types: func hello(name: String) -> Void{} //the above does not have a return value func hello(name: String) -> String { let ret = "Hello " + name return ret} To call the above function: let msg = hello(name: "Mary") //I am aware of the return value but don't want to use it: _ = hello(name: "Mary") You can also do this: @discardableResult func hello(name: String) -> String { let ret = "Hello " + name return ret } Multi-parameter functions: func hello(name: String, greeting: String) { } To call: hello(name:"Mary", greeting:"Whats up") You can define a parameter with default values. func hello(name: String, greeting: String = "Whats up"){} When calling, you can either call with the greeting or without it: hello(name: "Mary") hello(name:"Mary", greeting:"Good day") We can also declare multiple default values: func hello(name: String

Swift Basics - filtering

Filtering with the where statement: for number in 1...50 where number % 3 == 0 { } //get numbers from 1 to 50 that can be divided by 3 without remainder Filtering using for case: var pupilsWhoWon = [("Mary", 10), ("John", 50), ("Mary", 80)] for case let ("Mary", score) in pupilsWhoWon { print(score)} Filter out nil values: let myNum: [Int?] = [1, 2, nil, 3, nil] for case let .some(num) in myNum {   print(num) } //each optional value is an enumeration with either case none or some. If there is a value, it would have case some. You can filter out the numbers that have a value are are more than 3: for case let num? in myNum where num > 3 {} You can use if case statements for enumerations: enum Book{ case Title(String) case Edition(Int) case Author(String) } var thisBook = Book.Edition(2) if case let .Edition(num) = thisBook {print("This book's edition is \(num)")} OR if case let .Edition(num) = thisBook, num == 2 {} //Checks to see

Swift Basics - Switch Case

Switch case: switch speed {   case 10: print("10")   case 50: print("50")   default: print("Other") } Multiple: var c: Character = "e" switch c {   case "a", "e", "i", "o", "u": print("Vowel")  default: print("Consonant") } Switch within a range: switch x {   case 85...100: print("A")   case 70...84: print("B")   default: print("Others") } Adding other conditionals to a case: switch x {   case 85...100 where studentId == 8:   print("Congratulations!")   case 85...100:   print("A") } Note that if you place where studentId == 8 above case 85...100, it would never be reached as the first condition to meet the criteria will be reached.

Swift Basics - Tuples

You can use tuples to group multiple values of different types into a single value. var food = ("Ice cream", 'Strawberry", 3, 150) You can give each a name: var (dish, flavour, scoops, calories) = food To get an item from the tuple: var dish = food.0 var flavour = food.1 You can also create a tuple with a key:name association: var food = (dish:"Ice cream", flavour:"Strawberry", scoop:3, calories:150.2) You can use tuples in place of classes and objects that do not have any methods.

Swift Basics - Sets

Using the set type: each item must be unique. The items are not ordered. The type stored in the set must be hashable. A basic type (like string, int, double, float) are all hashable. They are able to compute hash values for themselves. To create an initialise a set: var mySet = Set<String>() //initialise values var mySet = Set(["ABC", "DEF", "GHI"]) //instead of var, you can use let Insert items into a set. If we try to insert something that is already there, it will be ignored. mySet.insert("JKL") To check to see if it has been inserted successfully: var results = mySet.insert("JKL") if results.inserted{} Get the number of items in a set: mySet.count Check to see if a set contains an item: var contain = mySet.contains("ABC") //will return true Iterating over each item in a set: for item in mySet { } Removing items in a set: var item = mySet.remove("ABC") mySet.removeAll() Construct sets from 2 sets: var set1 =

Swift Basics: Arrays

Collections and tuples Types of collections: Arrays, dictionaries, and sets. All items stored in collections have to be of the same type. Collections can be constant or variable. (Use let or var) Arrays Each item in an array is an element. We can initialise arrays like this: let firstArray = [1, 2, 3] We can also declare them like this (these arrays are empty at first): var secondArray = [Int]() var thirdArray: [Int] = [] We can create arrays to store String, Double, SelfCreatedObjects We can create arrays to store more than one type: var fourthArray: [Any] = [1, "Three"] We can also create arrays that can store objects of any class type: var fifthArray:[AnyObject] = [] We can initialise an array to have 5 elements, each having the number 1: var sixthArray = [Int](repeating: 1, count: 5) We can create 2 dimensional arrays: var twoD1 =[[1,2], [3,4],[5,6],[7,8]] var twoD2 = [[Int]]() To access the elements of an array: It starts with 0: print(firstArray[0]) //will print 1 To ac

Swift Basics - Dictionaries

Dictionaries They store key value pairs, like pupil name with pupil ID. To create and initialise a dictionary: var countries = ["US":"America", "IN":"India", "SG":"Singapore"] (can use let too if it is immutable) Declaring an empty dictionary: var d1 = [String:String]() var d2 = [Int:String]() To ensure that the type can be used as a key, the type used has to be hashable. To access the value based on the key: var nameOfCountry = countries["SG"] To get the count of a dictionary: var cnt = countries.count To check if a dictionary is empty: var isItEmpty = countries.isEmpty Updating the value of a key: countries["US": "United States"] OR var theOriginalValue = countries.updateValue("United States", forKey:"US") Adding a key-pair value to the dictionary: countries["MY"] = "Malaysia" OR var originalValue = countries.updateValue("Thailand", forKey:"

Swift Basics - Enumerations

Enumerations They can contain strings, characters, integers, or floating points. To define an enumeration: enum DaysOfWeek {   case Monday   case Tuesday   case Wednesday } OR enum DaysOfWeek {   case Monday, Tuesday, Wednesday  case Thursday, Friday, Saturday, Sunday } We can assign an enumeration value to a variable: var today = DaysOfWeek.Saturday We can use it with a switch case: switch today {  case .Monday: print("Monday")  case .Tuesday: print("Tuesday")  default: print("Another day") } We can also populate enumerations with raw values enum MyFavs: String {  case musicGenre = "Rock"  case movie = "Shindler's List"  case song = "Vindicated" } print("My fav song is : \(MyFavs.song.rawValue)") We can assign numbers: enum Months: Int  {  case January = 1  case February= 2 } print("The month January is month number \(Months.January.rawValue)") We can assign more than one value to each case of an enume

Swift Basics - Strings

Using strings: Declaring a multiple line string variable: var multiLineString = """ ABCD EFGHI """ You can add quotes in multiple line variables: var heSaid = """ He said,"Hello." """ To go through each character in a string: for char in nameOfString.characters {  print(char) }   OR nameOfString.map {  print($0) } Concatenate 2 strings: var c = a + b a += b b = "Hello \(a)" You cannot add another part of a string to a constant. Print in lowercase: a.lowercased() b.uppercased() Replace an occurrence of a string with another: nameOfString.replacingOccurences(of: "boy", with: "girl") Working with substrings Getting a string between the third and eighth character of a string: let starting = nameOfString.index(nameOfString.startIndex, offsetBy: 2) let ending = nameOfString.index(nameOfString.startIndex, offsetBy: 7) let theSubString = nameOfString[starting ..< ending] let newString = Strin

Swift Basics - Optionals

In Swift, nil is not a pointer to a non-existent object, it just means that it does not have a value. var str: String? means that it might or might not have a value. Optionals are used to deal with situations to avoid runtime errors in case variables have not been initialised. By declaring it as optional, we ensure that a variable's value is checked to not be nil being it is being used. Unwrapping means to get a value from an optional. Variables need to be a non-nil variable. They must always have a value. If there are times when we need the variable to have a nil value, we can make use of optionals. We can assign a nil value to an optional. We don't have to initialise it. When we are retrieving a value from an optional, we need to make sure that it is not nil. Here is how to declare an optional: var nameOfString: String? nameOfString = "ABC" if nameOfString  != nil {   var newString = nameOfString! + "DEF" } Here are a few ways to unwrap an optional Here is

Swift basics - the very basics (variables, constants, types)

To open the debug area: shift+command+Y Add images to swift playground: 1. command + 1 2. Drop image over to resources folder 3. Create an object with the image: var image = UIImage(named: "sc.png") Using the for loop: var j = 1 for i in 1...5 {   j += i } for in loop: used with collection or range of numbers: for index in 1...5 {   print(index) } for item in firstArray{} for (index, value) in dict1{} while x<7 {   x = Int(arc4random_uniform(10)) } ar4random above gives a random number between 0 and 9 Instead of do while, swift makes use of repeat while var x: Int repeat {   x = Int(arc4random_uniform(10)) } while x < 4 Add comments: // /* */ /// The triple slash is for documenting code For example: To document a function: /// ///The adding function will the take 2 parameters /// - parameter nameOfFirst: First number to add /// - parameter secondParameter: Second number to add /// - returns: the sum of the two numbers /// - throws: any error /// When you press the optio

Swift basics - Availability Attribute

Availability Attribute: Helps to ensure that a minimum OS is used: if #available(iOS 9.0, OSX 10.10, watchOS 2, *){//requirements met}else{} We can ensure that certain code is available where a certain OS is available: @available(iOS 9.0, *) //means iOS 9 or later func thisFunctionIsOnlyAvailableAfterIOS9(){} @available(iOS 9.0, *) //means iOS 9 or later struct thisStructureIsOnlyAvailableAfterIOS9{}

Swift basics - error handling

Error handling Guard statement If a condition if false, we can trap errors early: var x = 3 guard x > 10 else {  //do error handling here } If x is not greater than 10, error handling will be done. In a function, check that there is a valid value in an optional: func theFunction(str: String?) {   guard let theStr = str else   {     //error handling   } } Control statements You use control statements for error handling. Control statements include continue, break, fallthrough, guard, throws and return Continue: tells a loop to stop executing the code and go to the next iteration in the loop for i in 1 ... 10 {   if i % 2 == 0  {    continue   }  print("Odd number") } Break: If a criteria is met, it will get out of the loop. The for loop will not continue: for i in 1... 10 {  if i % 2 == 0  {   break  }  print("odd number") } The above will only print odd number once. Fallthrough: Used in switch statements switch food { case "Laksa" : print("Laksa&quo

Swift 4 basics - protocols

Protocols: Something like interfaces, where we describe the methods, properties and requirements of a type without providing implementation. Here is how to define a protocol: protocol MyProtocol{  var a: Int{get set}  var b: String{get set}  var readOnlyVar: String{get}  //var a, b, and c will have to be listed as properties in any class implementing the protocol  func getBSquared() -> Int //this method will have to be defined and implemented in the class that implements this protocol } To implement it in a structure: struct MyStruct: MyProtocol{} A structure can implement more than one protocol: struct MyStruct: Proto1, Proto2, Proto3{} If a class both implements and inherits, we can define the class by inheriting first, then by implementing: Class MyClass: TheParentClass, Proto1, Proto2{} Protocols can be used as types var aProto = Proto1 Can be stored in arrays: var proto: [Proto1] = [] You however, cannot create an instance of a protocol. You can create an instance of a class or