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 [email protected]
Top Related