@gernot [email protected]
##What we'll do
- Basics
- Optionals
- Classes, Extensions and Protocols
- Structs, Enums
- Memory Management? Debugging? Ask!
Play along in Playgrounds!
Mobile Development is…
…so today we'll concentrate on the language.
#A bit of history…
1972: C 1972: Smalltalk
1983: C++ 1983: Objective-C (2006: Obj-C 2.0)
1990: Haskell 1995: Java
2014: Swift
#[fit]Current Status
- Swift is still in Development
- Xcode will crash!
- Even long-term, the language will change
- If the language changes, your Apps will still run — but you'll have to revisit your code
- Apps for OSX and iOS
- Playgrounds
- Command Line Tools
#!/usr/bin/env xcrun swift -i
- REPL (for debugging)
#What is Swift designed for?
- Modern High Level Programming
- Objective-C Compatibility
- C Compatibility
- LLVM Optimization
NSString *name; //initialized with nil
double price; //initialized with 0
NSInteger position; //can never be nil, using NSNotFound instead
CGRect myRect; //uninitialized
let name = "Meier" //Implicit String, always initialized!
var favoriteColor: UIColor //has to be initialized!
var price = 39.90 //Implicit Double
var position: Int? //Optional Int, initialized nil
let myRect = CGRect(x:0, y:0, width:10, height: 10)
##Working with Optionals
Unwrapping:
if position != nil {
let newPosition = position! + 1 //implicitly an Int
}
Conditional Unwrapping:
if let myPosition = position {
let newPosition = position + 1
}
Implicitly unwrapped optionals
var position: Int!
newPostion = position + 1 //Attention, crashes if position is nil!
Only use when you're sure what you're doing!
Objective-C bridge still has a lot of implicitely unwrapped optionals. This will change (and break your code) — use them and check them as if they are optional
##Calling Methods on Optionals
var car: Car?
//[…]
car?.drive() //Does nothing when car == nil
car!.drive() //Crashes when car == nil
//Variable names are scoped!
if let car = car {
car.drive()
car.brake()
washcenter.wash(car)
}
#[fit]Functions
func sayHello() {
println("Hello")
}
hello()
func sayHello(name: String) {
println("Hello \(name)")
}
hello("Earthlings")
func sayHello(name: String, peace: Bool) {
println("Hello \(name)")
if peace println("We come in Peace")
}
hello("Earthlings", peace: true)
func sayHello(name: String, peace: Bool = true) {
println("Hello \(name)")
if peace println("We come in Peace")
}
hello("Earthlings")
func sayHello(salutation name: String) {
println("Hello \(name)")
}
hello(salutation: "Earthlings")
func sayHello(salutation salutation: String) {
println("Hello \(name)")
}
hello(salutation: "Earthlings")
func sayHello(#salutation: String) {
println("Hello \(name)")
}
hello(salutation: "Earthlings")
func sayHello(name: String, abductCows: () -> Void) {
println("Hello \(name)")
abductCows()
}
hello("Earthlings", {
//get cows
})
hello("Earthlings") {
//get cows
}
func sayHello(name: String, abductCows: (Int) -> Int) {
println("Hello \(name)")
println("Abducted \(abductCows(5)) cows")
}
sayHello("Earthlings") {
numberOfCows in
println("About to abduct \(numberOfCows) cows")
return 2
}
//About to abduct 5 cows
//Abducted 2 cows
//Look, Ma! Functional Programming!
typealias cowHandler = (Int) -> Int
func sayHello(name: String, abductCows: cowHandler) {
println("Hello \(name)")
println("Abducted \(abductCows(5)) cows")
}
let abduct: cowHandler = {
numberOfCows in
println("about to abduct \(numberOfCows) cows")
return 2
}
sayHello("Earthlings", abduct)
//Just for the record 😉
typealias 🐮 = (Int) -> Int
func sayHello(name: String, abductCows: 🐮) {
println("Hello \(name)")
println("Abducted \(abductCows(5)) cows")
}
let abduct: 🐮 = {
numberOfCows in
println("about to abduct \(numberOfCows) cows")
return 2
}
sayHello("Earthlings", abduct)
typealias cowHandler = (Int) -> Int
func sayHello(name: String, abductCows: cowHandler) {
println("Hello \(name)")
println("Abducted \(abductCows(5)) cows")
}
sayHello("Earthlings") {
_ in //ignore the parameters
println("This is a vegan UFO. We don't abduct any cows.")
return 0
}
let maximumAllowedWarpSpeed = 0.9999 //Global Constant
class UFO {
let maxWarpSpeed = 2.0
var currentSpeed = 0.0
func engage() {
self.currentSpeed = maximumAllowedWarpSpeed
//or
currentSpeed = maximumAllowedWarpSpeed
}
}
class UFO {
var currentSpeed {
get {
return warpdrive.currentSpeed
}
set {
//newValue automatically has the value to be set.
warpdrive.currentSpeed = newValue
}
}
}
class UFO {
//Only getter!
var currentSpeed {
get {
return warpdrive.currentSpeed
}
}
}
class UFO {
var currentSpeed { return warpdrive.currentSpeed }
}
class UFO {
var currentSpeed {
willSet {
if (newValue >= 1.0) {
println ("Prepare for Hyperspeed!")
}
}
didSet {
println("Huiiii")
}
}
}
##Initialiszers
let maximumAllowedWarpSpeed = 0.9999 //Global Constant
class UFO {
init(maxWarpSpeed: Double) {
self.maxWarpSpeed = maxWarpSpeed
}
let maxWarpSpeed: Double
}
Objects always need to be fully initialized
init() {
//First, initialize the object
super.init()
//From here on, you can use self & methods
}
##Lazy Initialisation
class TractorBeam {
}
class UFO {
lazy var tractorBeam = TractorBeam()
}
class TractorBeam {
init(energy: Double) {
//[…]
}
}
class UFO {
let availableEnergy = 3.45
lazy var tractorBeam: TractorBeam = {
return TractorBeam(energy: self.availableEnergy)
}()
}
extension UFO {
func activateLasers() {
//LAZERS!!
}
}
##Protocols
protocol Destroyer {
func activateLasers()
}
class SuperUFO: UFO, Destroyer {
func activateLasers() {
//LAZERS
}
}
var myUFO: Destroyer
##Optional Protocols
protocol Destroyer {
optional func activateLasers()
}
class SuperUFO: UFO, Destroyer {
func activateLasers() {
//LAZERS
}
}
var myUFO: Destroyer
//[…]
myUFO.activateLazers?()
struct numberPlate {
var city = "B"
var letters = "AB"
var numbers = 1234
var description: String {
return "\(city) - \(letters) \(numbers)"
}
}
var numberplate1 = numberPlate() // B - AB 1234
var numberplate2 = numberplate1 // B - AB 1234
numberplate2.letters = "CD" // B - CD 1234
// numberplate1 is still B - AB 1234
enum FuelType {
case Kerosine
case Plutonium
}
let fuel = FuelType.Kerosine
switch fuel {
case .Kerosine:
//[…]
case .Plutonium:
//[…]
}
enum FuelType {
case Kerosine
case Plutonium
case Spice(Int)
func energy() -> Double {
[…]
}
}
- iBooks: "The Swift Programming Language" & "Using Swift with Cocoa and Objective-C"
- Apples Swift Blog, NSHipster, Ole Begemann, Objc.io
- Apple Developer Forums (esp. Chris Lathner)
- iOS Dev Weekly Newsletter
- Meetups: swift.berlin, Berlin Swift Development
- Memory Management and ARC
- Inheritance, Initialization & Deinitialization
- Debugging & REPL
- Objective-C Bridge
- Namespacing, Frameworks and Modules
- Runtime Features and Swift Intermediate Language
- Generics and Functional Programming