Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling...

32
Integrating Swift and iOS 8 In Existing Applications

Transcript of Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling...

Page 1: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Integrating Swift and iOS 8 In Existing Applications

Page 2: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Integrating Swift In Existing Applications

Luke Toop Tyrone Trevorrow

@luketoop @aetherealle

Page 3: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

What is Swift, anyway?

Page 4: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

– Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/au/book/swift-programming-language/

id881256329?mt=11

“Swift combines the best in modern language thinking with wisdom from the wider Apple

engineering culture.”

New!

Page 5: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Benefits of Swift

As a developer

As a team

As a project

Page 6: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Benefits for DevelopersBetter* syntax than Objective-C

Better tools than Objective-C

Playgrounds

Compiler and Analyser

Completely automated memory model, instead of “mostly” automated

Better constructs

let swift = Syntax(like: objc, but: better!)

Page 7: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Generic Programming

Functional Programming

Optionals

Expressive Type System

Pattern Matching Cases

Enums With Associated Types

Structs With ARCCleaner Closures

Explicit Mutability

Page 8: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

func doSearch() { FlickrAPI.search(searchBar.text) { [unowned self] result in let photos = result["photos"] as? NSDictionary ?? [:] let photoList = photos["photo"] as? [NSDictionary] ?? [] let urls = photoList.map{ json -> NSURL in let (farm,server,id,secret) = (json["farm"],json["server"],json["id"],json["secret"]) return NSURL(string: "http://farm\(farm).staticflickr.com/\(server)/\(id)_\(secret)_b.jpg") } self.photos = urls self.reloadData() } }

- (void) doSearch { __weak typeof(self) weakSelf = self; [FlickrAPI searchFor: self.searchBar.text completion:^(NSDictionary *result) { typeof(self) strongSelf = weakSelf; if ([result objectForKey: @"photos"] != nil && [result[@"photos"] objectForKey: @"photo"] != nil) { NSArray *photos = result[@"photos"][@"photo"]; NSMutableArray *urls = [NSMutableArray arrayWithCapacity: photos.count]; for (NSDictionary *photoJSON in photos) { NSString *urlStr = [NSString stringWithFormat: @"http://farm%@.staticflickr.com/%@/%@_%@_b.jpg", photoJSON[@"farm"], photoJSON[@"server"], photoJSON[@"id"], photoJSON[@"secret"]]; [urls addObject: [NSURL URLWithString: urlStr]]; } strongSelf.photos = urls; [strongSelf reloadData]; } else { strongSelf.photos = nil; [strongSelf reloadData]; } }]; }

Old And Busted:

New Hotness:

Page 9: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Even if it made no difference to the developer, there are some advantages for teams switching to Swift...

!

Page 10: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Benefits for TeamsLower SLOC

Don't need experts in C quirks

Don't need experts in ObjC runtime

Expressive & Strict Typing: encourages and rewards better encapsulation

Easier for good devs to switch from C++/Python/Javascript to Swift

No headers!

Less crashes!

Less undefined behaviour!

Reduced defect rate!

Less specialised training!

Page 11: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Benefits for Projects

Future-proofing your code base

Speed and quality of development

Performance and reliability of releases

Page 12: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Carbon

“iPhone OS”

- (void) setThing: (id) aThing { if (aThing != _thing) { [_thing release]; _thing = [aThing retain]; } }

Page 13: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Future-proofing

No one knows what to expect

WWDC15: Swift / Objective-C for all new APIs?

When will new APIs be released for Swift first?

When will new releases be Swift only?

Page 14: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

What’s the Catch?

Page 15: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Not All Butterflies and RainbowsiOS 7 minimum

Objective-C interop problems

Swift calling ObjC is better than ObjC calling Swift

Weird bridging behaviour (NSRange, Optionals)

Compiler is currently much worse than Clang

Woeful C++ Support: Need to write either C wrappers or Objective-C wrappers

Cannot convert the expression's type '(($T5) -> ($T5) -> $T4) -> (($T5) -> $T4) -> $T4' to type 'U'

Page 16: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Static LibrariesReusable components in iOS projects traditionally use static libraries (.a files)

Swift code cannot be compiled into a .a file

What about Frameworks?

Frameworks require iOS 8.0

The short answer is: You cannot create or reuse Swift components without dropping iOS 7 support right now. 💩

This might change with a future seed (might even change tomorrow!)

Page 17: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Text

BridgingEmbedding Swift code in an Objective-C project

Page 18: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)
Page 19: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

// // ViewController.m // SwiftFun // // Created by Tyrone Trevorrow on 23/06/2014. // Copyright (c) 2014 My Amazing Company. All rights reserved. // !#import "ViewController.h" #import "SwiftFun-Swift.h"

// // Use this file to import your target's public headers that you would like to expose to Swift. // !#import "ViewController.h"

Objective-C Files:

For all Swift files, use the Bridging Header:

Use #import “ModuleName-Swift.h” to import all supported Swift classes into the Objective-C context

Import any Objective-C headers you want to be available in Swift

Page 20: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

ModulesAll Swift code must be contained in a module

Replaces the ancient arcane header system

Your project might not be module friendly!

Remember that static libraries are broken!

Page 21: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Swift Features Not Available From Objective-C

Generics

Swift structs

Swift enums

Curried functions

Nested types

Swift variadics

Swift-defined typealiases, global vars and top-level functions

Tuples

Optional protocols need to be @objc, so no protocol methods can use the Swift features above

If it’s cool, it’s probably on this list 😞

Page 22: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

CocoaPods

Page 23: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Dependency ManagementYou should be using it!

No Swift support for your own pods (yet!)

Can still be used within Swift code using bridging tricks

Over 6000 libraries available

Page 24: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

– https://github.com/CocoaPods/CocoaPods/issues/2272

“As we still need to support older deployment targets, we cannot simply switch everything over… The current roadmap for this looks

like so: !

1. Maintain the current Pods directory layout and use of xcconfigs. 2. In addition, generate Clang Modules maps. 3. Make it possible to generate Dynamic Framework targets from

CocoaPods libs.

Page 25: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

What Does This Mean For Objective-C?

Objective-C isn't legacy... yet

Apple’s existing products and tools are almost exclusively written in Objective-C

Swift will be the priority for Apple

New high-level frameworks are likely to be Swift-only (iOS9, OSX 10.11)

Low level frameworks will likely remain in C (with Swift annotations)

Page 26: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Bottom Line

Page 27: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

When To Use Swift

Starting a new app or game today? Use Swift!

New modules in existing apps

Only if iOS 7 and up, and if module is reasonably separated with clear interface — minimises bridging

Page 28: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

When To Avoid Swift

Writing a library or dependency

If your project has lots of C++

If your project has realtime concerns, such as Core Audio’s AudioUnits or Core Audio’s render thread

If your project is a multi-platform codebase

If you’re particularly averse to weird compiler messagesLLVM ERROR: Broken function found, compilation aborted!

Page 29: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

‘Modular’ Code

Page 30: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Refactor

Page 31: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

Resources

reddit.com/r/Swift

Apple Developer Forums

Official Apple Swift Blog

iBooks

TSBoilerplateSwift

https://github.com/ksm/SwiftInFlux

Page 32: Integrating Swift and iOS 8 In Existing Applications · Objective-C interop problems Swift calling ObjC is better than ObjC calling Swift Weird bridging behaviour (NSRange, Optionals)

That’s all, [email protected] [email protected] !

Luke on Twitter: @luketoop Tyrone on Twitter: @aetherealle