First stab at learning Swift went bloody well

Just finished doing the “Learn Swift 2 The basics” training on Lynda.com. Learning the language is pretty smooth with this tutorial. I’ll have to learn more are conditionals, unpacking, and bridging headers to combine Objective-C and Swift in the same project.

source: https://www.lynda.com/Swift-tutorials/Learn-Swift-2-Basics/437175-2.html

Questions for Pairing

  • Should we experiment in playgrounds?
  • Should we do the entire project?
  • Maybe start with basics in playground to get real time compilation

Swift Data Types


// let defines a constant that cannot be modified
// var defines a variable that is mutable
// swift compiler has inference
// write a = 5, compiler thinks it is an int
// explicit typing:
// var a : String = "text example"
// strings can be combined with +
// string interpolation, putting strings (or different data types) inside strings

var numDays = 5
let toPrint = "There are \(numDays) days in the weekend"

// arrays created like this
var myArray : [Int] = [3,5,7]
var myArray = [3,4,5]
var myArray2 : [Int] = Array() // needs explicit definition to add right type of data
myArray2.append(5)
var complexArray : [Any] = Array() // allows any kind of data type
complexArray.append(3) // adds int
complexArray.append("Hello World") // adds string
myArray.count
myArray.removeItemAtIndex(0)

// dictionaries created like this:
var myDictionary = ["apple":"red", "banana":"yellow"]
var myDictionary : [String:Int] = Dictionary()
myDictionary2["apple"] = 0
myDictionary2["banana"] = 1

// **optionals are advanced and unique to swift
// situations where a variable might not have a value

var c : Int? // tells compiler c might be nil or might have a value
var d = c! + 5 // must address that optional c is force unwrapped, only do when sure variable has value
if let nonOptioonalValue = c { // optional binding, only do if has value
  var e = nonOptionalValue + 5 // not executed if c is nil
}
import Foundation
var optString : String?
// I know this might be nil but still try it
optionString?.stringByAppendingString("more"); // if optionString is nil, you will get nil back from operation

// operations require operands to be of the same type
// if different, cast to same type
// curly brackets are always necessary in conditional statements
// switch statement allows case elements to be strings.
// no need to add break keyword after each case
// breaks automatic
// fallthrough keyword allows to go to next case without breaking

// guard statements
guard(t < 0) else { //functions like an if valid
  return
}
while loops
repeat {
  // runs once before the test
}while(i < 10)

// iterate through range of numbers
for index2 in 1...15 {
  index2 // increments itself from 1 to 15, prevents off by 1 errors
}

// iterate through array
let myArray = [1,5,10]
for a in myArray {
  a // prints out 1, 5 then 10
}

Functions


func sayHello(name: String) -> String { // says this function returns a String
  return "hello, \(name)" // example of string interpolation
}
func customGreeting(name: String, greeting: String) -> String {
  return "\(greeting), \(name)"
}
customGreeting("Bob", greeting: "Hi") // in swift common practice is to make first parameter not named, then rest are named

// force swift to disregard a named parameter
func sayHelloToFullName(firstName: String, _ lastName: String) -> String {
  return "Hello, \(firstName) \(lastName)"
}
sayHelloToFullName("Bob", "Smith") // does not require named parameter because of _ in function definition
strings get length
string.characters.count

CONSTRUCTS

  • classes are good for inheritance
  • structs have a limitation, no inheritance and are passed by copy, not reference
  • enums can include functions

// simple class definition
class myClass {
  var a = 3
  func classMethod() -> String {
    return "Return Value"
  }
}

var c1 =  myClass()
cl.a = 10
cl.classMethod()

// simple class definition with initializer
class myClass {
  var a : Int
  init(initialValue: Int) { // constructor
    a = initialValue
  }
  func classMethod() -> String {
    return "Return Value"
  }
}

var c1 =  myClass(initialValue: 15)
cl.a // initialized with 15
cl.a = 10
cl.classMethod()

// build struct
struct myStruct {
  var a = 4
  init(initialValue: Int) {
    a = initialValue
  }
  func structMethod() -> String {
    return "Return Value"
  }
}

var st = myStruct(initialValue: 12)
st.a
st.a = 16
st.structMethod() // all these are the same as class

<h4>// build enum</h4>

enum myEnum { // stores list of possible values
case Value1, Value2, Value3 // stores values with same keyword as switch
init() { // sets custom default initializer
  self = .Value2
}
// enums cannot store properties
static var testValues = ["Test1", "Test2", "Test3"]// can have static variables
func returnMyValueInStringForm() -&gt; String { // can have functions in them
  switch(self) {
    case .Value1: // enumeration is equal to first value
      return myEnum.testValues[0]
    case .Value2 // NOT CLEAN ON WHY THIS HAS A DOT NOTATION???
      return myEnum.testValues[1]
    case .Value3
      return myEnum.testValues[2]
    }
  }
}

var en = myEnum.Value1
var en2 = myEnum // implicitly sets with default init method
en.returnMyValueInStringForm()

Inheritance


class Employee {
  var yearsWorked : Double = 0
  var hasStockOptions : Bool = false
  var currentStatus : EmployeeStatus = .Active // sets with default EmployeeStatus
  enum EmployeeStatus {
    case Active, Vacation, LeaveOfAbsence, Temp, Retired
  }
}

class CEO : Employee, ExecutiveMember { // shows that this class implements ExecutiveMember protocol
  overrride init() {  // does a special init for this object
    super.init()
    hasStockOptions = true
  }

  var bonusAmount : Int {
    return 10000
  }

  func returnFullTitle() -> String {
    return "Chief Executive Officer"
  }
}

class CFO : Employee, ExecutiveMember { // can only implement one super class, but multiple protocols
  overrride init() {
    super.init()
    hasStockOptions = true
  }

  var bonusAmount : Int {
    return 5000
  }

  func returnFullTitle() -&gt; String {
    return "Chief Financial Officer"
  }
}

// creates protocol for objects that conform to this
**// protocol contains abstract method
protocol ExecutiveMember {  // protocol introduces method style, does not include implementation
  var bonusAmount : Int {
    get
  }
}

class Worker : Employee {

}

class TempEmployee : Employee {
  override init() { // sets default of this kind of employee to default .Temp
    super.init()
    currentStatus = .Temp
  }
}

let ceo = CEO()
ceo.yearsWorked = 25
ceo.bonusAmount // implements protocol and returns bonusAmount
ceo.returnFullTitle();
veo.currentStatus = .LeaveOfAbsence
ceo.currentStatus

let cfo = CFO()
cfo.bonusAmount
cfo.returnFullTitle()
cfo.currentStatus

let worker = Worker()
worker.currentStatus

let temp = TempEmployee()
temp.currentStatus
temp.returnFullTitle() // fails because does not implement returnFullTitle method

Storyboards

  • Build user interfaces in graphical environment
  • Only available as a project, not as playground
  • Any Any at bottom of layout shows the what kind of device this design is for
  • Control click on a label then drag to element you want to have it couple to in layout
  • ensures that the two elements stay close to each other when rendered on different layouts and screens
  • Create new view controller for any new screen you want
    select viewcontroller from side pane
    drag into the storyboard to be side by the other one
    control click on button in first view controller
    drag to other view
    now clicking button takes you to next view
  • ViewController.swift is stub that is build for first view controller
    Create swift file for second view controller
    make sure it implements view controller protocol
    Open storyboard
    set to class of secondviewcontroller

Set button action like this:

@IBAction func buttonPressed(sender : UIButton) {
  // button pressed
}

Segues allow view controllers to pass information between different view controllers.

NSUserDefaults

  • Persistent between launches
  • Accepts keyed ints, strings, dates, not all kinds
  • **what does as? mean? // yes it’s an optional, but how does that apply to a for each as?

Interacting with Objective C

Swift string can be converted to NSString with cast


let str = "Test String"
let nsStr = str as NSString

  • true for nsdictionary, nsarray, nsnumber, etc
  • Subclass objective C object types in swift is allowed
  • limitation of no way to subclass a swift object in objective c

Creating button in objc vs swift


objc: UIButton *button = [UIButton buttonWithType: UIButtonTypeSystem];
swift: let button = UIButton(type: .System)

  • Swift automatically shortens enums
  • **objc API, you might find that LLVM shortens enum values
  • Using objective C and swift in the same project
  • Xcode creates a bridging header
  • import objective c header files
  • add properties
  • Then in implementation, write method
  • And copy the method signature to the bridging header file

Misc Swift notes:

  • In Swift 2, we can only use print() to write something to the output. Apple has combined both println() and print() functions into one.
  • The only Xcode version that supports Swift 2.0. Xcode 7 is currently in beta.
  • click on bottom left icon to bring up console in playground
  • printing a named parameter in the print function
  • print(“1”, “2”, “3”, separator:”—“)
  • Hold down option and click on method name, Shows method signature
  • Hold down command and click on method name, Jumps to method definition.

Lingering Questions

  • Is Core Data is available in swift playgrounds
  • What unique content is posted on swift.org?
  • Can I run swift on linux?
  • Where are the best Swift 2.0 problem sets online?

Author: David Neely

Professional Software Developer. Technology and Web Coordinator at the University of Hawaii's Manoa Career Center.