Intro toswift1

57
Introduction to Swift Apple’s Objective-C Replacement

Transcript of Intro toswift1

Introduction to SwiftApple’s Objective-C Replacement

Agenda

- Who am I? - How Apple arrived at Swift - What’s new in Swift - Swift’s syntax & basics - Resources

What we will cover

Who am I?

- iOS + .NET Developer - Write on all things development - Game Developer (Specifically, Unity) - Founded Dreaming In Binary - Developer at HealthMEDX

Jordan Morgan

Apple’s road to Swift

Created in 1983 by Brad Cox & Tom Love

Built right on top of C

Added Object Oriented ideas (classes, objects, etc)

Objective-C is created

Apple’s road to Swift2 years later, Jobs licenses it for NeXT (NeXTSTEP)

1996, Jobs is back at Apple and NeXT is acquired

Object Oriented libraries separated out from the OS as an API called OpenStep

1997, Apples includes NeXT OS and APIs into new OS - “Rhapsody”. This became Mac OS X.

This is where we get “NS” from - NeXT Step

Objective-C is engrained into Apple’s technology stack

Apple’s road to Swift

Objective-C became the native language for iOS/OS X

Improved and iterated upon over the years

Works fine - but starts to show its age

Objective-C peaks

Apple’s road to Swift- Objective-C is not easy to learn

- Syntax is unusual and unfamiliar

- C is mixed in and heavily used in Foundation

- C baggage (.h & .m files, for example)

- No generics (leads to tedious casts)

- Overloading not supported

Objective-C’s weaknesses

Apple’s road to Swift

Keeps the best of Objective-C, such as named parameters

Brings in modern programming language advancements

Syntax is familiar - similar to PHP, Python, and Rust

In comes Swift!

What’s new in Swift

Type inference

Cool new features

var aString:String = "String variable"keyword name type initial value

What’s new in Swift

var 😼 = "Catface"

Type Inference

var anotherString = "Another string variable"

Variables can be unicode characters

Omit the type - it’s inferred to be a String

What’s new in Swift

String is lightweight like a C string

Powerful as an NSString

Concatenating is no longer a chore

Types

var twitterURL = "\(kTwitterURL) + \(twitterHandle)";

NSURL *twitterURL = [[NSURL alloc] initWithString:[kTwitterURL stringByAppendingString:twitterHandle]];

What’s new in Swift

var speakers = 20 var attendees = 300

var audience = "On average, there will be \(attendees / speakers) people at each session."

String Interpolation

Can even have expressions evaluated

No need for a mutable or immutable typed Strings

What’s new in Swift

The let keyword defines a constant

Constants

let speakers = 20 let attendees = 300

let audience = "On average, there will be \(attendees / speakers) people at each session."

- Opt for immutability - Forces you to think about your declarations - Safer for multithreaded environments - Optimization gains

What’s new in Swift

- Variables always initialized before use

- But what about nil?

- Objective - C nil = Pointer to a non existent object

- Swift nil = Absence of a value of a certain type

- Optionals - more on that later

Variable Initialization

What’s new in Swift

- Closures unified with function pointers

- Generics

- Tuples

- No more semicolons (though you can)

- and more

Other notable additions

If Statements

No parentheses required

Some basic and minor changes

Braces always required

if 1 < 2 { println("True") } else { println("False") }

CollectionsThey can work with any type - primitives included

Concise and powerful: NSArray *numAr = @[[NSNumber numberWithInt:0]];

Array and Dictionary

let numAr = [1]

let names: [String] = ["Jordan", "Jansyn"]Specify the type if you want:

Collections

Array

Literal declarations

Dictionary

let names = ["Jordan", "Jansyn", "Bennett"]

let namesAndAges = ["Jordan":25, "Jansyn":25, "Bennett": 1]

No more “@“ in front of strings either

CollectionsEasy to modify

Modify a collection with append(<T>):var modify = [“Jordan”] modify.appened(“Jansyn”) //["Jordan","Jansyn"]

Specify indexvar modify = ["Jordan"] modify[0] = "Jansyn" //["Jansyn"]

Use range operatorsvar modify = ["Jordan","Jansyn"] modify[0...1] = ["Bennett","Whitney"] //["Bennett","Whitney"]

Collections

Just define a new key

Modify a dictionary

var morganFam = ["Jordan":25] morganFam["Jansyn"] = 25

Editing value works the same wayvar morganFam = ["Jordan":25] morganFam["Jansyn"] = 26

Collections

If you want a collection with more than one type :

Varied types

var multiTyped: [AnyObject] = ["foo", 01, true, 44.5]

That said, try to keep them strongly typed

For most intents and purposes, AnyObject is analogous to id

Loops

for i in 0..<2 { println(i) } //Output: 0,1

Ranges

Half open range Closed rangefor i in 0...2 { println(i) } //Output: 0,1,2

LoopsEasily loop through characters in a stringFlexible

let abc = "abc"

for char in abc { println(char) }

In Objective-C :NSString *myStrings = @"abc"; for (NSInteger charIdx=0; charIdx < myStrings.length; charIdx++) { NSLog(@"%C", [myStrings characterAtIndex:charIdx]); }

LoopsExclude value from the range (use _)

Loops cont.

let base = 3 let power = 10 var answer = 1 for _ in 1...power { answer *= base }

Iterating over collectionslet morganFam = ["Jordan":25,"Jansyn":25,"Bennett":1]

//KVPs from dictionary come back as tuples for (name,age) in morganFam { println("\(name) is \(age) years old.") }

LoopsCondition - increment looping

Traditional C-style iteration

for var idx = 0; idx < MAX; idx++ { println("Index is \(idx)") }

No parentheses Initialization with var and not letWhile loops are here too

Switch Statements

No implicit fall through

Fallthrough

You can still “break” out before execution if finished

If you want to fallthrough, you can use fallthrough

Switch StatementsYou can get cute with them

Switches cont.

let anInt = 40 switch anInt { case 0, 1, 2: println("Tiny") case 3...5: println("Medium") case 6..<39: println("Large") case _ where anInt % 2 == 1: println("It's odd") case _ where anInt % 2 == 0: println("Nope, it's not odd, it's even") default: break }

Switch StatementsThe old days

Compared to Objective-C

NSString *morganFamMember = @"Jordan"; if ([morganFamMember isEqualToString:@"Jansyn"]) { NSLog(@"It's mom!"); } else if([morganFamMember isEqualToString:@"Bennett"]) { NSLog(@"It's the baby boy!"); } else if([morganFamMember isEqualToString:@"Whit"]) { NSLog(@"It's Jordan's sister!"); } else if([morganFamMember isEqualToString:@"Jordan"]) { NSLog(@"It's dad!"); } else { NSLog(@"We don't know who it is."); }

The new dayslet morganFamMember = "Jordan"

switch morganFamMember { case "Jansyn": println("It's mom!”) case "Bennett": println("It's the baby boy!") case "Whit": println("It's Jordan's sister!") case "Jordan": println("It's dad!") default: println("We don't know who it is.") }

Objective-C doesn’t support Switch with NSString

Optionals

We want the value - or to know it wasn’t found

A core concept of Swift

Optionals have ? by them

Means we get a value back - or nothing at all

Optionals

We could use magic numbers (i.e. -1)

Cont.

let jansynsAge:Int? = morganFam["Jansyn"]

NSNotFound if in Objective-C

Returns nil -or no value, or an int (Need to specify type)

OptionalsSo if it’s there, how do we get it?

Unwrapping

let jansynsAge:Int? = morganFam["Jansyn"]

if jansynsAge == nil { println("Jansyn is apparently timeless.") } else { let foundAge = jansynsAge! println("Jansyn is \(foundAge) years old.") }

Unwrap the value (i.e. the !)

No need to specify the type, the compiler knows

OptionalsThis is a common pattern, shorthand is like so (no !):

Short syntax

if let foundAge = jansynsAge { println("Jansyn is \(foundAge) years old.") }

If you know the value is there, you can unwrap it directly:var name: String? = "Jordan"

let anotherJordan = name!

println(anotherJordan)

You’re crashing if you’re wrongIf forced unwrapped, you don’t need to set it to a var.

Optional ChainingWhat if you want a value that could be housed around other nil values?

Query multiple optionals

class Residence { var street:String? }

class Person { var humbleAbode:Residence? }

var aPerson = Person()

Optional ChainingUse ? operator to use optional chaining

Cont.

class Residence { var street:String? }

class Person { var humbleAbode:Residence? }

var aPerson = Person()

if let theStreet = aPerson.humbleAbode?.street { println("The street is \(theStreet)") } else { println("Person has no street") }

Remember, any optional must be unwrapped via !

FunctionsDefined with func keyword

Overview

func printName() { println("It's Jordan") }

Named parameters, like Objective-Cfunc printName(name:String) { println("It's \(name)”) }

FunctionsDenote return type with ->

Return types

func printNameWithGreeting(name:String) -> String { return "It's \(name), how ya doin' today?" }

Define default valuesfunc printNameWithGreeting(name:String = "Jansyn") -> String { return "It's \(name), how ya doin' today?" }

FunctionsReturn tuples

Multiple return types

func nameAndAge() -> (String, Int) { return ("Jordan",25) }

Decompose them to access valueslet (name,age) = nameAndAge()

println("\(name) is \(age) years old.")

FunctionsGive meaningful names to return values

Name multiple return values

func nameAndAge() -> (name:String, age:Int) { return ("Jordan",25) }

let Jordan = nameAndAge()

println("\(Jordan.name) is \(Jordan.age) years old.")

//Jordan is 25 years old.

ClosuresMuch like blocks in Objective-C

Similar functionality

Contain some code, you can pass them aroundLambdas or anonymous functionslet aClosure = { println("This is a closure") }

Compiler sees it like this:let aClosure: () -> () = { println("This is a closure") }

ClosuresNotice that’s similar to a function’s signature

Syntax

let aClosure: () -> () = { println("This is a closure") }

func aClosure: () -> () = { println("This is a closure") }

Functions are just named closures

ClosuresDefine in the formal parameter list

Passed as a parameter

func doTaskRepeated(count: Int, theTask: () -> ()) { for i in 0..<count { theTask() } }

Calling itdoTaskRepeated(10, { println("A complex and awesome task.") })

ClosuresDefine closure as the last parameter in formal parameter list

Trailing closure

doTaskRepeated(10) { println("A complex and awesome task.") }

Looks like control flow statement

Classes

No more import because Swift has no implementation file

Much like Java and .NET

No need to explicitly define a base class

class Person { }

Classes

class Jordan { let name = "Jordan" }

Properties

Swift provides the backing store for you

By default, all entities have internal accessclass Jordan { let name = "Jordan" private let movieMostWatchedPastMonth = "Frozen" }

ClassesUse internal, or nothing at allExposing properties

class Jordan { let name = "Jordan" internal var age = 25 private let movieMostWatchedPastMonth = "Frozen" }

let aJordan = Jordan()

//Grew up quick during this talk aJordan.age = 35

Notice you don’t need “new” in front of the type

ClassesYou can define custom getters and setters

Computed properties

class Jordan { let name = "Jordan"

var myLocation:(x:Float,y:Float) { get { return (10,30) } set { self.myLocation.x = newValue.x self.myLocation.y = newValue.y } } }

…can even use tuplesCreate a read only computed property - just omit setter

Classesinit() keywordInitialization

class Jordan { let name = "Jordan" var age = 25 init() { //No need to return self } }

Can also initialize constant valuesclass Jordan { let name = "Jordan" let hobby = "" init() { //No need to return self } init(hobby:String) { self.hobby = hobby } }

var aJordan = Jordan(hobby: "Basketball")

- if you are inheriting, call super.init()

ClassesFires just before and right after value changesProperty Observers

class Bennett { private let setCurfew = 9 //p.m. var curfew : Int { willSet { if curfew > setCurfew { println("GROUNDED") } } didSet { if curfew < setCurfew { println("I am glad you obey.") } } } init() { self.curfew = setCurfew } }

ClassesWork the same way as functionsMethods

Only need to use self when property has the same name as a parameter in the function’s signatureclass Bennett { var nickName = "Benny" func changeNickName(nickName: String) { self.nickName = nickName println("Bennett's new nickname is \(self.nickName)") } }

Classes

You don’t even need to specify one

A note on initializers

super.init needs to happen last in custom initializers

Sole purpose is to initialize values for the class

Structs

Still works the same way

Not much has changed

- Doesn’t support inheritance - Value types

Think of them as you do in your OOP language of choice

EnumerationsValue types

Enums

They can have raw values (like in C)

enum BestNFLTeams:Int { case StLouisRams = 1, Patriots, Bucs, Chiefs }

BestNFLTeams.StLouisRams.toRaw() //Prints 1, obviously

EnumerationsDon’t always need underlying valuesenum Directions { case North, South, East, West }

//Compiler infers Directions as type var directionToGo = Directions.North

Also, compiler will again infer the typelet lbl = UILabel() lbl.textAlignment = .Right

Value type constants have all constant members Reference type constants can have mutable members

EnumerationsAssociate values within an enumAssociated Values

enum RamsVictory { case ByOnePoint case ByPoints(Int) }

var ramsWinBig = RamsVictory.ByPoints(24)

Even custom propertiesenum RamsVictory { case ByOnePoint, ByPoints(Int) var winSummary:String{ switch self{ case .ByOnePoint: return "Rams by one." case .ByPoints(let points): return "Rams win big by \(points)!" } } }

var ramsWinBig = RamsVictory.ByOnePoint println(ramsWinBig.winSummary) //Rams by one. ramsWinBig = RamsVictory.ByPoints(14) println(ramsWinBig.winSummary) //Rams win big by 14!

Access Modifiers

Three modifiers

Recently Added

- Private - Available only from within source file - Internal - Available to entire module that includes

the definition (i.e. app or framework) - Public - Intended for use with APIs, means entity

can be accessed by any file that imports the module

There’s much more

Interoperability with Objective-C

Lots of new features

Extensions

Automatic Reference Counting

Pattern Matching

Functional Programming

Resources- www.dreaminginbinary.co

- The Swift Programming Language (iBook)

- The Swift Blog

- WWDC Videos

- @dibsoftware

- @jordanmorgan10

- facebook/dreaminginbinary