Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full...

81
Catching Up with Swift Ash Furrow, Artsy

Transcript of Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full...

Page 1: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Catching Up with SwiftAsh Furrow, Artsy

Page 2: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

“What’s the worst that could happen?”

Page 3: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Agenda

1. Swift was needed

2. Swift met those needs, mostly

3. Writing Swift is great, mostly

4. Using Swift in production

5. The future of Swift

Page 4: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Swift Was Needed.

Page 5: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• From the early 1980’s

• Originally, a C preprocessor

• Then an advantage

• Now a burden

Page 6: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• Moderate use until the mid 2000’s

• Used to make OS X apps

• Niche market

• Then the iPhone happened

Page 7: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Source: http://bit.ly/1E2BOCs

Page 8: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• Sudden interest, despite:

• Esoteric syntax

• Unusual memory management

• Arcane knowledge

Page 9: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• Three distinct groups of developers emerged:

• First wave, developers from the 80’s/90’s.

• Second wave, OS X developers from the 2000’s.

• Third wave, developers attracted by the iPhone.

Page 10: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Friction.

Page 11: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• Tension.

• Disenfranchisement.

• Resentment.

Page 12: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

—John Siracusa

“While hardware performance increases over time, the human capacity to deal with

complexity does not.”

Page 13: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C• New features were developed by Apple:

• Dot property syntax.

• Closures.

• Decreased boilerplate, headers.

• Automatic reference counting.

• Collection literals.

• Primitive boxing syntax.

Page 14: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

“See? Objective-C is getting better! We don’t need to replace it!”

—First/Second Wave Developers

Page 15: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

False.

Page 16: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Language Evolution

• Machine code.

• Assembly.

• Procedural languages (C).

• Object-oriented languages (C++, Objective-C).

• Virtual machines (Java, C#, Ruby, etc).

Page 17: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

archaicEventually, writing Objective-C will seem

competitive disadvantage.and relying on it would be a

Page 18: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

“Eventually.”

Page 19: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

decades.Replacing your home-grown programming

language takes

Page 20: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C

• Could not escape its C roots.

• Apple began work on Swift in 2010.

Page 21: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Swift

Objective-C improved

of

because

Page 22: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Objective-C Replacement• Needs to…

• abandon all C roots.

• be memory managed.

• have native unicode strings, native collections.

• be concise.

• have named parameters.

Page 23: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Swift Met Those Needs.Mostly.

Page 24: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Swift

• Announced June 2014.

• Betas released until a 1.0 in the Autumn.

• “Objective-C without the C.”

• Mischaracterization.

Page 25: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

SwiftNeeded to…

! abandon all C roots.

! be memory managed.

" have native unicode strings, native collections.

" be concise.

" have named parameters.

Page 26: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Abandon C Roots

• Swift needed to have full Objective-C interop.

• Which means full C interop.

• It’s possible to write Swift to interact with C APIs.

• It’s ugly and discouraged.

• Well, I discourage it anyway.

Page 27: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Be Memory Managed

• Objective-C introduced ARC in 2011.

• Replaced garbage collection on OS X.

• Replaced manual memory management on iOS and OS X.

Page 28: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Be Memory Managed

• Automatic Reference Counting.

• Same as manual memory management.

• Inserted for the developer at compile-time.

• Reasoned about and optimized by compiler.

Page 29: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!
Page 30: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Be Memory Managed

Pros

• Familiar, stable technology.

• No garbage collector overhead.

Cons

• Can’t detect reference cycles.

Page 31: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Native Unicode Strings

• Got ‘em.

• Strings are a Swift struct.

• Bridgeable to Objective-C NSString instances.

• Handle double-byte Unicode characters.

Page 32: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Native Unicode Strings

func �() -> RACSignal { return hideAllTheThingsSignal()}

func #(snapshottable: Snapshotable) { expect(snapshottable).to( recordSnapshot() )}

Page 33: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Native Collections

• Collections are also Swift structs, on generics.

• Array<T>, Dictionary<K, V>, and Set<T>.

• Bridgeable to Objective-C equivalents.

• Concise syntax.

Page 34: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Be Concise

• Subjective, but I’m happy.

• Simple things are easy.

• Difficult things are possible.

Page 35: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Named Parameters

• Optional(ish)

• Compiler does weird things for Objective-C interop.

¯\_(�)_/¯

Page 36: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Named Parameters

func compare(lhs: String, to rhs: String) -> Bool { return lhs == rhs}

compare("Hi", to: "Hello")

Page 37: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Writing Swift is Great.Mostly.

Page 38: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

different fromProblem-solving in Swift needs to be

Objective-C syntax.problem-solving with

Page 39: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!
Page 40: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Generics

• Objective-C is dynamically typed.

• Swift is statically typed.

• Awesome.

• (ish).

• Compile-time type safety.

Page 41: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Generics

• Objective-C distinguishes primitives and classes.

• Swift is all like (�°□°��� ���

• Arrays, dictionaries, and sets all use generics.

Page 42: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Genericsstruct Stack<T> { private var contents = Array<T>()

mutating func push(value: T) { contents.append(value) }

mutating func pop() -> T { return contents.removeAtIndex(0) }

var isEmpty: Bool { return countElements(contents) == 0 }}

Page 43: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Generics

var intStack = Stack<Int>()var stringStack = Stack<String>()var stackStack = Stack<Stack<AnyObject>>()

intStack.push(1)intStack.pop() // Returns 1

Page 44: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Lazy Swift

• Language-level concept of lazy evaluation.

• Applied automatically to global variables.

• Can be applied to any property.

Page 45: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Lazy Swift

• Assigned on first access.

• Can be overridden by setting before first access.

• Really cool trick with closures.

Page 46: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Lazy Swift

class MyClass { lazy var name = "Ash Furrow"}

MyClass().name // Returns "Ash Furrow"

let instance = MyClass()instance.name = "Orta Therox"instance.name // Returns “Orta Therox"

Page 47: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Lazy Swiftclass MyClass { lazy var name = "Ash Furrow” lazy var greeting: String = { return "Hello, \(self.name)" }()}

MyClass().greeting // Returns "Hello, Ash Furrow"

let instance = MyClass()instance.name = "Orta Therox"instance.greeting // Returns "Hello, Orta Therox"instance.name = "Eloy Durán"instance.greeting // Returns "Hello, Orta Therox"

Page 48: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Extending Types

• Objective-C has “categories” to extending existing classes.

• Swift has “extensions”, instead.

• The work on all types.

Page 49: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Extending Typesextension Int { var hours: NSTimeInterval { return NSTimeInterval(3600 * self) }}

extension NSTimeInterval { var fromNow: NSDate { return NSDate(timeIntervalSinceNow: self) } var ago: NSDate { return NSDate(timeIntervalSinceNow: -self) }}

4.hours.fromNow4.hours.ago

Page 50: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Index Paths

• Used to identify cells in a table view.

• Section, row.

• Lots of horrendous code.

• It’s so bad.

• Seriously bad.

Page 51: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Index Pathsif (indexPath.section == 0) { if (indexPath.row == 0) {

} else if (indexPath.row == 1) { } else if ...} else if (indexPath.section == 1) { if (indexPath.row == 0) {

} else if (indexPath.row == 1) { } else if ...} else if ...

Page 52: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Index Pathsif (indexPath.section == 0) { if (indexPath.row == 0) {

} else if (indexPath.row == 1) { } else if ...} else if (indexPath.section == 1) { if (indexPath.row == 0) {

} else if (indexPath.row == 1) { } else if ...} else if ...

Page 53: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Index Paths

switch (indexPath.section, indexPath.row) {case (0, 0):case (0, 1):case (1, 0):case (1, 1):default: // nop}

Page 54: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

better?Is that

Page 55: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

No.

Page 56: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Index Pathsswitch (indexPath.section, indexPath.row) {case (0, let row): // Executed for any section 0, row is row.case (let section, 0) where section % 2 == 1: // Executed for first rows of odd sections.case (let section, let row) where validate(section): // Executed when validate() returns true.default: // Executed on all other cases.}

Page 57: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

better?Is that

Page 58: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Maybe.

Page 59: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Let’s look for new ways to solve familiar problems.

Page 60: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Let’s ask other communities how they solve problems.

Page 61: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Swift in Production

Page 62: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!
Page 63: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!
Page 64: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Open Source by Default

• Decided to develop the app in the open.

• Because why not?

• No, seriously. Why not?

• Helpful for asking for assistance from others.

• “Here’s my code – what’s wrong?”

Page 65: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

github.com/artsy/eidolon

Page 66: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

August

• Swift had been out for two months.

• Stability had improved.

• Swift seemed ready.

Page 67: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Nope.

Page 68: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

September

• The language was great.

• Lots of frustration with tools.

• 3rd party tools weren’t ready, or didn’t exist.

• So we built some.

• And contributed to others.

Page 69: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

October

• Running behind schedule.

• “Hard deadline.”

• Explored options to speed up development.

• Brought on an extra developer to help.

Page 70: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

—My boss

“We don’t expect to meet our deadline.”

Page 71: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

We made our deadline.

$

Page 72: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Burnout.

Page 73: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

technical debt.

Significant

Page 74: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Problem Solving• Compiler optimizations segfault the compiler.

• Disable optimizations.

• App is too slow without optimizations.

• Buy faster iPads.

• Tools didn’t exist.

• So we built them.

Page 75: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

hands on.Swift is still

Page 76: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

awesome.But it’s also

Page 77: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Future of Swift

Page 78: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Safe Bets

• Tools will continue to improve.

• Always a year away from being stable.

• Language will continue to be awesome.

• And get more awesomer.

Page 79: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Predictions

• More functional-esque APIs from Apple.

• More functional-esque APIs from the community.

• No Swift-only APIs from Apple, for now.

• Apple doesn’t want to disenfranchise first/second wave developers.

Page 80: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

Recap

1. Swift was needed

2. Swift met those needs, mostly

3. Writing Swift is great, mostly

4. Using Swift in production

5. The future of Swift

Page 81: Catching Up With Swift - chariotsolutions.com · Abandon C Roots • Swi! needed to have full Objective-C interop. • Which means full C interop. • It’s possible to write Swi!

@ashfurrow

@ashfurrow

leanpub.com/yourfirstswiftapp

Thanks!