swift


option click a variable to see where ti si

doesn't need semicolon
you dont need main funciton to start

swift playground: automatically execute all the time

swift is typed with type inference. Type doesnt change once set
var firstName = "Chip"
var isActive = true
var myVariable :Int          //Float, Double,Bool, String, Character

let daysInWeek = 7        //constant

print("d")

swift doesnt convert int to double, Double(temp) to convert. Swift does not implicitly convert one type into another.

String interpolation  \( )
let city = "Los Angeles"
var temp = 75
print("The high for \(city) is \(temp) degrees." )


//////////////////////////////////////
if number >= 5 {

} else {

}
//////////////////////////////////////
switch number {
case 5 :

case 7:

case 8...10:     //closed range operator, doesnt need break

default:
     break
}
//////////////////////////////////////
var some_collection = 1...10           // 1..<10 //half open range operaor 1...99
for each_item in some_collection
{
    print("a")
}

//////////////////////////////////////

functions
constant parameter
func myfunc(name:String){ // name is set as constant
    print("myfunc \(name)")
}
myfunc("mort")

variable parameter
func myfunc(var a:Int){  // a is set as variable and can be changed
    a += 1
    print("myfunc \(a)")
}
myfunc(1)

set return value
func myfunc() -> String{
     return "Hello"
}
myfunc()

default value
func myfunc2(name:String = "My name"){
    return "myfunc \(name)"
}
myfunc2()
myfunc2("mort")

multiple parameters: first parameter can be implicit, others should be named
func myadd(a:Int = 10, b:Int=20) -> String{
    return "result = \(a), \(b)"
}
myadd(45)
myadd(b:200)
myadd(45, b:200)

external param name

func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
      return s1 + joiner + s2
}

In this version of the join function, the first parameter has an external name of string and a local name of s1; the second parameter has an external name of toString and a local name of s2; and the third parameter has an external name of withJoiner and a local name of joiner.

You can now use these external parameter names to call the function unambiguously:

  • join(string: "hello", toString: "world", withJoiner: ", ")

Arrays are zerobased, typed, var makes it variable, let makes it constant
let days = [13, 17, 19]
var myarr : [String]
myarr = ["a", "b"]
myarr.append("c")
myarr += ["d"]
myarr.insert("e", atIndex:0)
myarr.removeLast()
myarr.removeAtIndex(3)
myarr.count
for each_item in myarr {

}

    for (index, value) in shoppingList.enumerate() {
    print("Item \(index + 1): \(value)")
    }

Dictionaries, associative array, map, hash table
key can be any object
all keys one type, all values one type
var namesOfIntegers = [Int: String]()


    namesOfIntegers[16] = "sixteen"
    namesOfIntegers = [:]    // namesOfIntegers is once again an empty dictionary of type [Int: String]
      var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]

products.updateValue("Bicycle", forKey:73) //if exists update if not add. returns old value or nil
products[55] = nil //remove key/val pair
products.removeValueForKey(73) //remove key/val pair
products.count
for (key,val) in products {
    
}


Tuple: ("Hey", 13.5, true, 5)
var myTuple=(5, "abcd")

func getSongAndDuration() -> (String, Int){
  return ("song name", 5)
}
let temp = getSongAndDuration()
print("\(temp.0) with length of \(temp.1)" )

OR NAME TUPLE ITEMS

func getSongAndDuration() -> (name:String, length:Int){
  return ("song name", 5)
}
let temp = getSongAndDuration()
print("\(temp.name) with length of \(temp.length)" )

let (mysong, mylength) = getSongAndDuration()   // name new variables

optionals if the value can be nil. use ?
vat temp :Int?
if temp != nil{
   print("the temprature is \(temp!)")    // ! is forced unwrapping, works if we know the optional variable has a value and not just nil, otherwise get runtime error
}

Optional
var states = ["AZ":"Arizona", "CA":"California"]
var nv = states["NV"] // the result is optional because the key may or may not be present
var ca = states["CA"]

if let fullName = states["AZ"]{
    print(fullName) // if optional is not nil. it already forced unwraps it
    print(nv) //"nil"  //string nil
    print(ca)  //Optional("California")
} else{
    print("not found")
}

enum
enum weekdays {
  case sat
case sun
case mon
}

var day:weekdays
day = weekdays.sat
day = .sat  //we already know the type
or
var day2 = weekdays.sat
switch day2{
case .sat:
cae .sun:
case .mon:

}


closure
func myfunc(){

}

//simplest closure, but it is unused
{
   println("hi")
}

let myclosure = {
    println("hi1234")
}
func performFivetimes(closureparam:() -> ()){
    for i in 1...5{
        closureparam()
    }
}
performFivetimes(myclosure)
performFivetimes(  {println("hey") ; println("you're a bad ass")}   )


//a function that takes no arameters and returns nothin
func test () -> () {

}

//a closure that takes no arameters and returns nothin
var testclosure = { () -> () in
    
}


//sorted is a function in swift
//sorted(array_to_sort, closure_to_compare)
let unsortedArr = [5 ,2, 6, 8 , 10, 4]
let sortedArr = sorted(unsortedArr, {(a:Int, b:Int) -> Bool in return a<b})
sortedArr

create bits of code and start passing them arround (code injection)




Class Player {   / either set default values or initialize
   var name : String
   func sayHi(){
      println("Hi")
   }
   init(name){  //reserved keyword we don;t  need func for it , to set default values
      self.name = name
   }

    deinit {
    //cleanup code. doesnt take any parameters, doesnt return any values. you dont need it unless g.g. close db connection. calling deinit is not under your control. swift uses automatic reference counting ARC
     }
}

var jake = Player() // this will instantiate
jake.name = "2"

class GoldPlayer:Player{  //inheritance

func newMethod(){}
override func sayHi(){super.sayHi()}

}


when calling class functions we can leave first param unnamed but the rest shoud be named when calling

Accessibility
private: only accessible from within the same source code file
internal: default, accessible across code files, but must be within the same compiled module
public: accessible from any module that has imported yours, e.g. frameworks across deiffrent projects
final: make function unoverridable or class
for a method to be public its class has to be public and vice versa for other accessibility levels


class Person {
   
    var firstName: String
    var lastName:String
    var fullName:String{
        get{
            //return computedproperty
            return firstName + " " + lastName
        }
        set{
            //split "newValue" into two pieces
            var nameArr = newValue.componentsSeparatedByString(" ")
            firstName = nameArr[0]
            lastName = nameArr[1]
        }
    }
   
    init(first:String, last:String){
        firstName = first
        lastName = last
    }

}

var per = Person(first:"Jen", last:"Barber")
per.fullName = "mor sha"  //calls setter
per

for a comouted property we dont need a set method. you can omit get block
class Person {
    class var a : Int{ return 5 }   //class variable
    lazy var lv = 4;  // will not be evaluated unless requested
    var firstName: String
    var lastName:String
    var fullName:String{
            //return computedproperty
            return firstName + " " + lastName
    }
   
    init(first:String, last:String){
        firstName = first
        lastName = last
    }

class func {}  //class level method
}

Person.a

property observers: run some code whenever some property changes
add a code block right at the end of the property definition


class Player{
    var name:String = "Ali"{
        willSet{
            println("about to change to \(newValue)")
        }
       
        didSet{
            println("Have changed name from \(oldValue)")
        }
    }
}

var p =  Player()
p  //nothing prints
p.name = "john"  //prints

you cant add observers to lazy prperties just regular ones

Structure vs class
Strucures are value types (pass by value) value is copied. Int, double, float, bool, String, array, dictionary
classes are rereence types (pass by referenece) original object

just change class to struct if you want it to be pass by value and any changes to it not affecting its original form when it gpes to a function
when you define a struct wift will automatically generate a memberwise initializer for you even if you haven't defined an init

Structs do not take part in inheritance, or have deinit

object identity check only works for objects not structs(string, int array ,...). checks references
===  //identical to
!== //not identical to

Nil coalescing operator ??
we may have a value or we may be nil. if we have a value in the optional we'll use that if not we'll provide a substitute variable and we'll use that instead
var personalSite:String?
let defaultSite="http://www.google.com"

var website:String
if personalSite != nil{
    website = personalSite!
} else{
    website = defaultSite
}
OR
var website = personalSite ?? defaultSite

type check
if object is ClassName
object as ClassName (e.g. cast from parent to child)
OR try to see if it is of that type then down cast
let childObject = object as? ClassName   //returns optional
if childObject != nil { childObject!.method() }   //use ! to forcibly unwrap it before accessing any of its functionality
OR also mix unwrpping as before in the if itsef
if let childObject = object as? ClassName {
        childObject.method() // no need for !
}

Any(anything), AnyObject(has to be obj)
Use is, as, as? to check and downcast

As long as you import framerowkrs swift strings which are structures and not technically objects they are bridged to objctive-c nsstring objects.
    var obj:AnyObject
    obj = ""
    obj = tuple or closure wont work

protocol a list of methods that you want some class to perform and or properties you want a class to have
protocol CleanerProtocol {
   
    func cleanFloors()
    func emptyTrash() -> Bool
   
    //properties
    var brokenBulbs: Int {get}  //readonly or read write
}

class MyClass : SuperClass, CleanerProtocol{
    func cleanFloors(){}
    func emptyTrash() -> Bool{ return true}

    var brokenBulbs: Int {return 55}

}

Extension  add our own new methods and properties to an existing type without subclassing it. And you don't have to have the source code for it.
extension String {

//add methosd or properties that you'd like
    func reverseWord(){return " "}
}

var a = ""
a.reverseWords()

Generics
Get all benefits of strongly typed objects in returns. Instead of using

let myInts = [123, 456, 789, 345, 678, 234]
let myStrings = ["red", "green", "blue"]
let myObjects = [Player(), Player(), Player()]

func displayArray<T>(theArray:[T]) -> T{
    println("Printing the array:")
    for eachItem in theArray {
        print(eachItem)
        print(" : ")
    }
    println()
    let finalElement : T = theArray[theArray.count-1]
    return finalElement
}

var finalInt = displayArray(myInts)
++finalInt

var finalString = displayArray(myStrings)
finalString.uppercaseString










Comments