Bringing Swift into your Objective-C Projects

Post on 08-Apr-2017

1.540 views 2 download

Transcript of Bringing Swift into your Objective-C Projects

Bringing Swift into your

Objective-C Projects

Before we go any further…

Hold the tomatoes, I don’t hate Objective-C

Why does this matter?

Apple is all in

Learning Curve

Better Apps

Not going to discuss

• Swift Syntax

• Value vs Reference types

• How to convince your team

Sit Back &

Relax

Let’s Dive In

The Journey

Rewind to June 2014

Still Learning iOS 7

it’s that time of the year

no golden ticket

I was all ears

drinking mimosas with friends, watching

and then, all of the sudden

Hair Force One gets on stage and…

And so the journey began…

started studying & practicing,

used Swift for anything I could think of,

wrote some tutorials,

taught classes at work,

and tech reviewed a couple of books.

I was ready

Two Big Ideas

Two Big Ideas

1. Learn by Doing, but not doing too much

2. Maximize Benefits

Learn by Doing, but not doing too much

Big Idea 1

{1} Jump

{2} One View Controller

{3} Everything above view controller

Learn

{1} Jump

{2} One View Controller

{3} Everything above view controller

{1} Jump

{2} One View Controller

{3} Everything above view controller

Learn

{1} Jump

Back at work…

inherited Objective-C project

and we thought, should we start using Swift?

Fellowship Formed

took the plunge

Why on Earth would I want to start writing Swift

when I have deadlines?

Why Swift

• Faster & More Stable Apps

• Less Typing, I’m More Efficient

• It’s the future

So where to start?(Architecturally)

User Interface

UIApplication

UIApplicationDelegate

Core Logic

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewController

UIView

UIWindow

UIViewController

UIView

Started at the top…

now we’re here

{1} Jump

{2} One View Controller

{3} Everything above view controller

{1} Jump

{2} One View Controller

{3} Everything above view controller

Learn

{2} One View Controller

when we talk view controller it includes

the root view

Swift

Objective-C

User Interface

UIApplication

UIApplicationDelegate

Core Logic

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewController

UIView

UIWindow

UIViewController

UIView

User Interface

UIApplication

UIApplicationDelegate

Core Logic

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewControllerUIViewController

UIView UIView

UIWindow

UIViewController

UIView

Why did we start here?

Why did we start here?

• Minimize Risk

• Nice Set-up

• It’s Clean

Minimize Risk

Minimize Risk

• Don’t have to learn the whole language

• Easy U-turn

• Small and contained

Nice Set-up

Nice Set-up

• Flow Swift safety up into view controllers

• Setup for actually improving app

• Critical for re-writes

It’s Clean

It’s Clean

• One single file

• Easy to coordinate within team

• Don’t have to worry about things ObjC can’t see

Ok, so started building my first Swifty view controller

first step…

you’ll need to import Objective-C headers in

the bridging header

got my .swift view controller ready to build

time to build

started writing some autolayout code

using Masonry, and…

Misty Mountains

Swift does not support macros

Masonry uses macros

but…

there’s a Swift version!

let me just go update my podfile…

Mines of Moria

cannot package Swift in static libraries

wait what? really!?

doesn’t CocoaPods output static libraries?

bingo.

use_frameworks!{if targeting iOS 8 and above}

Encountered Balrog

Parse SDK pod didn’t like living in a framework

… domino effect

So watch out, you will hit a snag…

good news is,

Parse SDK now works with use_frameworks!

Ok, back to building the view controller

looks like I need some logging…

no problem, CocoaLumberjack’s

already in my podfile :]

Mordor's Black Gate

remember, Swift does not

support macros

it’s ok because…

CocoaLumberjack version 2.0.0

doesn’t macro

there’s a migration guide on GitHub

and don’t forget to run all your schemes

build and run…

Shelob

Tweaks

ALSO based on macros…

Just need to replace macros with Swift code

Check out ‘Using from a Swift Project’ section in

Tweaks README on GitHub

Things we ran into

• Lumberjack

• Masonry/SnapKit

• Cocoapods / Parse

• Tweaks

don’t let this scare you

Swift is being adopted at an incredible pace

Ok, view controller complete…

time to plug it in

in code or

Interface Builder

In code

in container view controller #import {module}-Swift.h

Interface Builder

do nothing! (special)

{1} Jump

{2} One View Controller

{3} Everything above view controller

{1} Jump

{2} One View Controller

{3} Everything above view controller

Learn

{3} Everything Above

View Controller

moved on up to root view controller

Core Logic

User Interface

UIApplication

UIApplicationDelegate UIWindow

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewControllerUIViewController

UIViewController

UIView UIView

UIView

Core Logic

User Interface

UIApplication

UIApplicationDelegate UIWindow

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewControllerUIViewController

UIViewController

UIView UIView

UIView

and up again…

Core Logic

User Interface

UIApplication

UIApplicationDelegate UIWindow

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewControllerUIViewController

UIViewController

UIView UIView

UIView

Core Logic

User Interface

UIApplication

UIApplicationDelegate UIWindow

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewControllerUIViewController

UIViewController

UIView UIView

UIView

So far

So far

• We implemented a new view controller in Swift

• We re-implemented root view controller in Swift

• We re-implemented app delegate in Swift

We got a taste of Swift

{1} Jump

{2} One View Controller

{3} Everything above view controller

{1} Jump

{2} One View Controller

{3} Everything above view controller

Learn

this next step is crucial

Maximize BenefitsBig Idea 2

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

Maximize Benefits

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

Maximize Benefits

{1} Think Vertical

Probably the most important topic of this talk.

it’s tempting to continue building view controllers

it’s also tempting to move on to core logic

but first,

let’s understand how Swift can help

make your apps better

better means material improvement

actually improving your app

if Swift can’t have a material impact on

your product…

then WHO CARES!

but Swift can!

How?

Safety & Speed

Let’s focus on safety

Safety means less chance of crashing

How

How

• Static typing

• Enforcing nullability & non nullability

• Immutability & value semantics

These are Swift only features

Objective-C code that calls Swift code does not benefit

So we want to use Swift types across as many

sub-systems as we can

this means across UI - Core Logic boundary

so how did we use this to our advantage?

we went vertical

we identified vertical slices

what’s a vertical slice?

Core Logic

User Interface

UIApplication

UIApplicationDelegate UIWindow

Persistence Networking Other Utilities

UIView

UIViewControllerUIViewController

UIViewController

UIView

UIView

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

VC VC

V V

Vertical Slice

we then re-factored our view controller to communicate with

core logic using Swift types

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

VC

V

VC

V

P

N

O

pure Swift core logic, only for pure Swift

view controllers

Key Insight use Swift types across

the entire stack

remember, we are trying to maximize

our use of Swift

ok so that’s what we did, you might be

wondering…

why not start at the bottom?

why not just build the core logic in Swift?

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

VC VC

V V

VC

V

VC

V

VC

V

I hear this a lot

so quick sidebar, here’s the argument

{this goes for codebases that will be worked on for

the foreseeable future}

let’s say we decide to do this

if we go horizontal…

we won’t maximize our use of Swift

and we’ll paint ourselves into a corner

why?

if we start at the bottom, we’ll definitely have Objective-C

consuming our Swift code

Why is that bad?

we’ll end up designing for least common

denominator

Objective-C View Controller

Objective-C View Controller

Objective-C View Controller Objective-C View Controller

Core Logic Objective-CSuperclass

Swift Core Logic

Core Logic Objective-CSuperclass

Swift Core Logic

Core Logic Objective-CSuperclass

Swift Core Logic

we’ll want Objective-C and Swift view controllers

to use our Swift base

Objective-C View Controller

Swift View Controller

Objective-C View Controller

Objective-C View Controller Objective-C View Controller

Core Logic Objective-CSuperclass

Swift Core Logic

Core Logic Objective-CSuperclass

Swift Core Logic

Core Logic Objective-CSuperclass

Swift Core Logic

we’ll end up building non Swifty interfaces

between UI and core logic

this will leak deep into both UI and core logic

Objective-C Superclass

Swift Subclass

Objective-C ObjectObjective-C Object

Objective-C Object

Objective-C Object

Swift Class Object

Swift Class Object

Objective-C Superclass

Swift Subclass

Objective-C ObjectObjective-C Object

Objective-C Object

Objective-C Object

Swift Class Object

Swift Class Object

& will continue over time

let’s say we decide to go pure Swift and we re-write all of our view controllers

without a re-factor, those Swift view controllers will interface with existing core logic layer

and we’ll end up with a pure Swift codebase that doesn’t

use the safety features

that’s crazy

but you say, there’s a way around this…

Objective-C Core Logic Superclass

Swift Core Logic Subclass

Objective-C View Controller Objective-C View Controller Swift View Controller

why go through all these

gymastics?

• Everyone on the team will have to understand this

• Requires a ton of discipline & deep understanding

another way to look at it is…

we’ll end up using only a portion of Swift,

Accessible • Classes• Reference Semantics• Int backed Enums

Unaccessible • Generics• Tuples• Enumerations defined in Swift without Int raw

value type• Structures defined in Swift• Top-level functions defined in Swift• Global variables defined in Swift• Typealiases defined in Swift• Swift-style variadics• Nested types• Curried functions

Yes, we can start at the bottom

and yes, it will work

but we’re not taking advantage of everything

Swift has to offer

Ok, sidebar over…

instead

find new or existing vertical slices you can

write in Swift

if it’s not clear where the vertical slices are…

re-factor your Objective-C code first

that’s safety

Let’s talk Speed

boils down to essentially no

runtime overhead

that’s speed

Knowing Swift’s strengths, you can improve your

existing apps with Swift code

and gradually expand its surface area within

your project

back to the journey…

Ready to test!

not so fast…

Enterprise codesign

Ready to ship!

not so fast…

Conditional Compile

#if Debug …

#elseif Release …

#endif

Google #ifdef replacement in swift

Time to cut release build and…

ship it!

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

Maximize Benefits

{2} Swift will Change

Then Apple released Swift 1.2

it’s just a dot release

piece of cake, there’s even a migrator :]

‘cause it’s just a dot release

right?

nope!

took two full days to migrate

Swift is still evolving

good news is…

you don’t have to uptake new versions

immediately {for now}

point is, you WILL run into this

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

Maximize Benefits

{3} Plan for the Future

things are good

time to think about the long haul

Game plans

Game plans

• Mixed Project

• Modularize

• Re-write (Go big or go home)

Mixed Project Game plan

Modularize Game plan

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

VC VC

V V

VC

V

VC

V

VC

V

Persistence

Networking

Other Utilities

VC

V

VC

V

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

Persistence

Networking

Other Utilities

VC

V

VC

V

Module / Cocoa Touch Framework

VC VC

V V

VC

V

VC

V

VC

V

You Might Run Into

You Might Run Into

• Exporting Module Maps

• Some system frameworks aren’t mapped to modules yet (common crypto, libxml, etc.)

Google, “clang module map”

Re-write Game plan

You don’t have to re-write your app

as a matter of fact you probably shouldn’t

best game plan depends on your app’s architectural topology

depends a lot on the size of the code base and how well architected/structured it is

can you modularize it?

and how can you slice it?

3 Gameplans

• Go big or go home

• Modularize

• Mixed

we decided…

Go big or go home

Mordor

this is the least practical path…

but why not?

we re-wrote all of our vertical slices

one by one

UIApplication

UIApplicationDelegate

Persistence

Networking

Other Utilities

UIViewController UIView

VC

V

VC

V

P

N

O

P

N

O

VC

V

VC

V

P

N

O

VC

V

P

N

O

VC

V

P

N

O

UIApplication

UIApplicationDelegate

UIViewController UIView

VC

V

VC

V

VC

V

VC

V

VC

V

Persistence

Networking

Other Utilities

we made it!

pure Swift goodness

and we shipped it!!!

Steps we took

• Identified Vertical Slices

• Re-wrote each vertical slice one at a time

• Maximized our use of Swift

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

{1} Think Vertical

{2} Swift will Change

{3} Plan for the Future

Maximize Benefits

Two Big Ideas

1. Learn by Doing, but not doing too much

2. Maximize Benefits

that was quite a journey

what happened next?

new project

pure Swift project

having done mixed to full helped A TON

we shipped that too…

just a week ago

and now we are here

Whew…

The Point

learned a lot along the way without risking too

much at any time

you can start writing Swift right now

without worrying

you have options

What Advice Can I Give?So what did I learn?

What Advice Can I Give?

• What to learn first

• Objective-C consuming Swift interop

• Objective-C selectors in Swift

What to learn first

What to learn first

• Optionals, optionals, and optionals!

• Reference types vs Value types

• Initializers, BE CAREFUL

• Classes (inheritance, overrides, etc.)

• New Objective-C features (nullability, etc)

Exposing Swift to Objective-C

Objective-C can’t see pure Swift

Tips

Avoid writing pure Swift code for

Objective-C components

Stick to subclassing Apple framework classes

or create your own Objective-C super

classes

Objective C Superclass

Pure Swift Class, Struct, Enum

Swift subclass

Pure Swift Class, Struct, EnumPure Swift Class, Struct, Enum

Pure Swift Class, Struct, Enum

Objective C Consumer

Swift talks to Swift, Objective-C talks to

Objective-C

Yes, you CAN get Objective-C talking to

Swift classes, but why?

Don’t have to wonder

• Can Objective-C take value types?

• Can Objective-C take my Swift enum?

• Can Objective-C take my closure?

• Do I need an adapter?

• etc.

“If you never import a Swift class in Objective-C code, you

don’t need to worry about type compatibility” - Apple

let’s talk Objective-C Selectors

Swift is static, not dynamic

we have to understand how Objective-C selectors work

in a static Swift world

when to use @objc and @dynamic

some quotes from our friends at Apple

“Requiring @dynamic dispatch is rarely

necessary”

“you must use the @dyanamic modifier when you know that

the implementation of an API is replaced at runtime"

“If your Swift class inherits from an Objective-C class, all of the methods

and properties in the class are available as Objective-C selectors.”

This is important when

• using target-action

• using Key Value Coding / Key Value Observing

• (oh no!) swizzling

Wrapping up…

I survived

you can do it too

you don’t have to jump in all at once

do it your way, at your pace

learn the language basics & interop

so that then you can look at the benefits of Swift to improve your apps

plan it out, be intentional

you don’t have to re-write anything

you don’t have to compromise your

team’s commitments

there will be bumps

you know what to expect

you are ready

New File… that’s all it takes

Go Swift

The end. René CacheauxClient Architectrcacheaux@atlassian.com

@RCachATXrene.cacheaux@gmail.com