...and Beyond!
To Swift 2
About me
• iOS developer since 2010
• Swift since day 1
• Transitioning to Swift
• RayWenderlich.com
• CocoaConf
• Wash U
• Swift 2 Essential Training on lynda.com
• Principal iOS Architect at Care Otter
WWDC 2014
without the C
Objective-C
without the GCC
Objective-C
Chris Lattner
GCC
LLVM
Swift
WWDC 2015
Open Sourcing Swift
Swift Open Source
swift.org
Swift Open Source
swift.org
Swift
Who are you?
• Doing iOS development?
• For more than 1 year?
• Swift?
• Swift 2?
What I’ll cover
• To Swift from Objective-C
• To Swift 2
• ...and Beyond!
• What’s coming in Swift 2.2 and 3.0
To Swift from Objective-C
Optionals
Classes
Functions &
Closures
Enumerations
Reference
Types
Value
Types
Structures
Integers
Floating-Points
Booleans
Characters
Strings
Arrays
Dictionaries
Tuples
To Swift from Objective-C
Value types are passed by copy
Value
Typex = y = xValue
Type
Value
Type copy
To Swift from Objective-C
Reference types are
passed by reference
x = y = xReference
Type
Reference
Type
To Swift from Objective-C
Objective-C Swift
To Swift from Objective-C
NSString *greeting = @"Hello"; let greeting = "Hello"
To Swift from Objective-C
NSString *greeting = @"Hello"; let greeting: String = "Hello"
No Semicolons
To Swift from Objective-C
NSMutableString *greeting = @"Hello"; var greeting = "Hello"
To Swift from Objective-C
NSMutableString *greeting = var greeting = "Hello"
greeting += ", world!"[greeting appendString:@", world!"];
[@"Hello" mutableCopy];
To Swift from Objective-C
NSMutableString *greeting = var greeting = "Hello"
[greeting appendString:@", world!"];
[@"Hello" mutableCopy];
greeting = greeting.stringByAppendingString(", world!")
To Swift from Objective-C
NSMutableString *greeting = var greeting = "Hello"
greeting += ", world!"[greeting appendString:@", world!"];
[@"Hello" mutableCopy];
NSLog(@"%@", greeting); // 2016-... Hello, world! NSLog("%@", greeting) // 2016-... Hello, world!
NSLog(greeting) // 2016-... Hello, world!
print(greeting) // Hello, world!
print("Scott said: (greeting)")
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2; // Int
// Int
let two = 2
let negativeOne = -1
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2; let two: UInt = 2
// Intlet negativeOne = -1
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2; let two = 2 as UInt
// Intlet negativeOne = -1
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2;
// Intlet negativeOne = -1
let two: UInt = 2
let one = negativeOne + twoNSInteger one = negativeOne + two; !
error: ambiguous use of operator '+'
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2;
// Intlet negativeOne = -1
let two: UInt = 2
NSInteger one = negativeOne + two; let one = negativeOne + Int(two)
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2;
// Intlet negativeOne = -1
let two: UInt = 2
NSInteger one = negativeOne + two; let one = negativeOne + Int(two)
let threePointOneFour: Float = 3.14CGFloat threePointOneFour = 3.14;
let π = M_PI // Double, 3.141592653589793
let ! = "What's that smell?"
NSString *greeting = @"Hello!"; let greeting = "Hello!"
let a: Character = "a"char a = 'a';
BOOL thisMuchIs = let thisMuchIs =YES; true
id anyObject = [NSObject new]; let anyObject: AnyObject = NSObject()
let numberOne = NSNumber(integer: 1)
To Swift from Objective-C
NSInteger negativeOne = -1;
NSUInteger two = 2;
// Intlet negativeOne = -1
let two: UInt = 2
NSInteger one = negativeOne + two; let one = negativeOne + Int(two)
let threePointOneFour = 3.14 // Doublelet threePointOneFour: Float = 3.14CGFloat threePointOneFour = 3.14;
let π = M_PI // Double, 3.141592653589793
let ! = "What's that smell?"
NSString *greeting = @"Hello!"; let greeting = "Hello!"
let a: Character = "a"char a = 'a';
BOOL thisMuchIs = let thisMuchIs =YES; trueNO;
id anyObject = [NSObject new]; let anyObject: AnyObject = NSObject()
let numberOne = NSNumber(integer: 1)
NSRange range = NSMakeRange(0, 5); let rangeInclusive = 0...5
let rangeExclusive = 0..<5
To Swift from Objective-C
NSMutableString *greeting = var greeting = "Hello"
greeting = nilgreeting = nil;
[@"Hello" mutableCopy];
if (greeting) {
// ...
}
!
error: nil cannot be assigned to type 'String'
To Swift from Objective-C
NSMutableString *greeting =
greeting = nilgreeting = nil;
[@"Hello" mutableCopy];
if (greeting) {
// ...
}
var greeting: String? = "Hello"
if let greeting = greeting {
// ...
}
greeting?.isEmpty
greeting?.characters.first?.hashValue
var dateOfBirth: NSDate! =
NSDate(timeIntervalSince1970: 20581200)
dateOfBirth.descriptionWithLocale(NSLocale.
currentLocale())
print(greeting!.characters.first!)!
error: unexpectedly found nil while unwrapping an Optional value
To Swift from Objective-C
NSMutableString *greeting =
greeting = nil;
[@"Hello" mutableCopy];
if (greeting) {
// ...
}
var greeting: String? = "Hello"
if let greeting = greeting {
// ...
}
greeting?.isEmpty
greeting?.characters.first?.hashValue
var dateOfBirth: NSDate! =
NSDate(timeIntervalSince1970: 20581200)
dateOfBirth.descriptionWithLocale(NSLocale.
currentLocale())
print(greeting!.characters.first!)
//greeting = nil
To Swift from Objective-C
let letters = ["A", "B", "C"]NSArray *letters = @[@"A", @"B", @"C"];
To Swift from Objective-C
NSArray *letters = @[@"A", @"B", @"C"]; let letters: [String] = ["A", "B", "C"]
To Swift from Objective-C
NSArray *letters = @[@"A", @"B", @"C"]; let letters: Array<String> = ["A", "B", "C"]
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSArray *letters = @[@"A", @"B", @"C"];
let numbers = [1: "One", 2: "Two", 3: "Three"]
let letters = ["A", "B", "C"]
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSArray *letters = @[@"A", @"B", @"C"]; let letters = ["A", "B", "C"]
let numbers: [Int: String] = [1: "One", 2: "Two",
3: "Three"]
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSArray *letters = @[@"A", @"B", @"C"]; let letters = ["A", "B", "C"]
let numbers: Dictionary<Int, String> = [1: "One",
2: "Two", 3: "Three"]
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSSet *uniqueValues = [NSSet setWithArray:@[@1,
@2, @3, @1]];
print(uniqueValues) // [2, 3, 1]
NSArray *letters = @[@"A", @"B", @"C"];
let uniqueValues: Set<Int> = [1, 2, 3, 1]
let letters = ["A", "B", "C"]
let numbers = [1: "One", 2: "Two", 3: "Three"]
let httpResponse: = (200, "OK")
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSSet *uniqueValues = [NSSet setWithArray:@[@1,
@2, @3, @1]];
print(uniqueValues) // [2, 3, 1]
NSArray *letters = @[@"A", @"B", @"C"];
let uniqueValues: Set<Int> = [1, 2, 3, 1]
let letters = ["A", "B", "C"]
let numbers = [1: "One", 2: "Two", 3: "Three"]
let httpResponse: (Int, String) = (200, "OK")
To Swift from Objective-C
NSDictionary *numbers = @{@1 : @"One", @2 :
@"Two", @3 : @"Three"};
NSSet *uniqueValues = [NSSet setWithArray:@[@1,
@2, @3, @1]];
print(uniqueValues) // [2, 3, 1]
NSArray *letters = @[@"A", @"B", @"C"];
let uniqueValues: Set<Int> = [1, 2, 3, 1]
let letters = ["A", "B", "C"]
let numbers = [1: "One", 2: "Two", 3: "Three"]
let httpResponse: (code: Int, text: String) =
(code: 200, text: "OK")
let httpResponseCode = httpResponse.code // 200
let httpResponseText = httpResponse.1 // OK
func getHttpStatus() -> (code: Int, text: String) {
return (200, "OK")
}
To Swift from Objective-C
let names = ["Moe", "Larry", "Curly"]
if names.count > 0 {
for name in names {
print(name)
}
}
NSArray *names = @[@"Moe", @"Larry", @"Curly"];
if (names.count > 0) {
for (NSString *name in names) {
NSLog(@"%@", name);
}
}
func printNames() {
guard names.count > 0 else { return }
names.forEach { print($0) }
}
To Swift from Objective-C
NSInteger score = arc4random_uniform(101);
switch (score) {
case 100:
// ...
break;
default:
break;
}
let score =
switch score {
default:
break
}
arc4random_uniform(101)
case 99, 100:
print("Top 2%")
fallthrough
case 95...100:
print("Great job!")
case let n where n % 2 == 0:
print(n, "is even")
To Swift from Objective-C
NSInteger score = arc4random_uniform(101);
switch (score) {
case 100:
// ...
break;
default:
break;
}
let score =
switch score {
default:
break
}
99
// Prints "Top 2%"
// Prints "Great job!"
case 99, 100:
print("Top 2%")
fallthrough
case 95...100:
print("Great job!")
case let n where n % 2 == 0:
print(n, "is even")
To Swift from Objective-C
// In prepareForSegue:sender:…
if let identifier = segue.identifier {
switch (identifier, segue.destinationViewController) {
}
}
case ("ShowControls", is ControlsViewController):
// ...
case ("ShowDetail", is DetailViewController):
// ...
default:
break
To Swift from Objective-C
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
+ (void)doSomething {
// ...
}
class func doSomething() {
// ...
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
+ (void)doSomething {
// ...
}
static func doSomething() {
// ...
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
+ (void)doSomething {
// ...
}
static func doSomething() {
// ...
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
+ (void)doSomething {
// ...
}
static func doSomething() -> Void {
// ...
}
To Swift from Objective-C
func addThis(this: Int, andThat that: Int) -> Int {
return this + that
}
- (void)addThis:(NSInteger)this andThat:(NSInteger)that {
return this + that;
}
+ (void)doSomething {
// ...
}
static func doSomething() {
// ...
}
addThis(1, andThat: 2)
func addThisAndThat(this: Int, _ that: Int) -> Int {
return this + that
}
addThisAndThat(1, 2)
To Swift from Objective-C
class SomeClass: NSObject {// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
let title: String
init(title: String) {
self.title = title
}
}
To Swift from Objective-C
class SomeClass: NSObject {// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
let title: String
init(title: String) {
self.title = title
}
}
To Swift from Objective-C
class SomeClass: NSObject {// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
static var aStaticValue = 1
let title: String
init(title: String) {
self.title = title
}
}
To Swift from Objective-C
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
class SomeClass: NSObject {
static var aStaticValue = 1
let title: String
init(theTitle: String) {
title = theTitle
}
}
To Swift from Objective-C
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
class SomeClass: NSObject {
static var aStaticValue = 1
let title: String
init(title: String) {
self.title = title
}
}
To Swift from Objective-C
SomeClass *someClass = [[SomeClass alloc]
initWithTitle:@"A Mighty Instance"];
To Swift from Objective-C
let someClass = SomeClass(title: "A Mighty Title")SomeClass *someClass = [SomeClass new];
someClass.title = @"A Mighty Instance";
To Swift from Objective-C
SomeClass *someClass = [SomeClass new];
someClass.title = @"A Mighty Instance";
let someClass = SomeClass()
error: missing argument for parameter 'title' in call
!
To Swift from Objective-C
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
class SomeClass: NSObject {
static var aStaticValue = 1
let title: String
init(title: String) {
self.title = title
super.init()
}
}
To Swift from Objective-C
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
class SomeClass: NSObject {
static var aStaticValue = 1
let title: String
init(title: String) {
super.init()
self.title = title
}
}
!
error: property 'self.title' not initialized at super.init call
To Swift from Objective-C
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
class SomeClass: NSObject {
static var aStaticValue = 1
?
}
var title: String
To Swift from Objective-C
class SomeClass
static var aStaticValue = 1
var title: String
}
// SomeClass.h
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject
@property (copy, nonatomic) NSString *title;
- (instancetype)initWithTitle:(NSString *)title;
@end
// SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
- (instancetype)initWithTitle:(NSString *)title {
if (self = [super init]) {
self.title = title;
return self;
}
return nil;
}
@end
{
?
To Swift from Objective-C
Properties
Methods
Subscripts
Initializers
Extensions
Adopt Protocols
Class
✓
✓
✓
✓
✓
✓
Structure
✓
✓
✓
✓
✓
✓
Enumeration
✓
✓
✓
✓
✓
✓
To Swift from Objective-C
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
};
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
}
To Swift from Objective-C
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
NSString *title;
};
!
error: ARC forbids Objective-C objects in struct
To Swift from Objective-C
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
var title: String
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
// NSString *title;
};
To Swift from Objective-C
let coordinate = Coordinate(x: 0.0, y: 0.0, z:
0.0, title: "Origin")
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
var title: String
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
// NSString *title;
};
struct Coordinate coordinate = {10.0, 10.0, 10.0};
To Swift from Objective-C
let coordinate = Coordinate(x: 0.0, y: 0.0, z:
0.0, title: "Origin")
enum Heading: Int {
case North, South, East, West
}
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
var title: String
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
// NSString *title;
};
struct Coordinate coordinate = {10.0, 10.0, 10.0};
typedef NS_ENUM(NSInteger, Heading) {
HeadingNorth,
HeadingEast,
HeadingSouth,
HeadingWest
};
To Swift from Objective-C
let coordinate = Coordinate(x: 0.0, y: 0.0, z:
0.0, title: "Origin")
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
var title: String
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
// NSString *title;
};
struct Coordinate coordinate = {10.0, 10.0, 10.0};
typedef NS_ENUM(NSInteger, Heading) {
HeadingNorth,
HeadingEast,
HeadingSouth,
HeadingWest
};
enum Heading {
case North, South, East, West
}
To Swift from Objective-C
let coordinate = Coordinate(x: 0.0, y: 0.0, z:
0.0, title: "Origin")
let movement = Movement.North(distance: 20.0)
struct Coordinate {
var x: CGFloat
var y: CGFloat
var z: CGFloat
var title: String
}
struct Coordinate {
CGFloat x;
CGFloat y;
CGFloat z;
// NSString *title;
};
struct Coordinate coordinate = {10.0, 10.0, 10.0};
typedef NS_ENUM(NSInteger, Heading) {
HeadingNorth,
HeadingEast,
HeadingSouth,
HeadingWest
};
enum Heading {
case North, South, East, West
}
enum Movement {
case North(distance: Double)
case South(distance: Double)
case East(distance: Double)
case West(distance: Double)
}
To Swift from Objective-C
- (NSString *)fullName {
return [NSString stringWithFormat:@"%@ %@",
self.firstName, self.lastName];
}
- (void)setTitle:(NSString *)title {
NSLog(@"Old title: %@", _title);
_title = title;
}
struct Person {
let firstName: String
let lastName: String
}
var fullName: String {
return "(firstName) (lastName)"
}
var title: String {
didSet {
print("Old title: " + oldValue)
}
}
To Swift from Objective-C
// ViewController+UITableViewDataSource.m
#import "ViewController.h"
@interface ViewController (UITableViewDataSource)
@end
// ViewController+UITableViewDataSource.m
#import "ViewController+UITableViewDataSource.h"
@implementation ViewController (UITableViewDataSource)
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
// ...
return cell;
}
@end
extension ViewController: UITableViewDataSource {
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")!
// ...
return cell
}
}
To Swift from Objective-C
@IBDesignable class DesignableView: UIView { }
extension UIView {
@IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
}
}
@IBInspectable var borderColor: UIColor? {
get {
return layer.borderColor != nil ?
UIColor(CGColor: layer.borderColor!) : nil
}
set {
layer.borderColor = newValue?.CGColor
}
}
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.masksToBounds = newValue != 0
layer.cornerRadius = newValue
}
}
}
To Swift from Objective-C
UIView.animateWithDuration(1.0, animations: {
// ...
}, completion: {
print("Done!")
})
[UIView animateWithDuration:1.0 animations:^{
// ...
} completion:^(BOOL finished) {
NSLog(@"Done!");
}];
(finished: Bool) in
To Swift from Objective-C
UIView.animateWithDuration(1.0, animations: {
// ...
}, completion: {
print("Done!")
})
[UIView animateWithDuration:1.0 animations:^{
// ...
} completion:^(BOOL finished) {
NSLog(@"Done!");
}];
finished in
To Swift from Objective-C
UIView.animateWithDuration(1.0, animations: {
// ...
}, completion: {
print("Done!")
})
[UIView animateWithDuration:1.0 animations:^{
// ...
} completion:^(BOOL finished) {
NSLog(@"Done!");
}];
UIView.animateWithDuration(1.0, animations: {
// ...
}) { _ in
print("Done!")
}
finished in
To Swift from Objective-C
UIView.animateWithDuration(1.0, animations: {
// ...
}, completion: {
print("Done!")
})
[UIView animateWithDuration:1.0 animations:^{
// ...
} completion:^(BOOL finished) {
NSLog(@"Done!");
}];
UIView.animateWithDuration(1.0, animations: {
// ...
}) { _ in
print("Done!")
}
var fileContents = {
// Some complex work
return "..."
}()
finished in
To Swift from Objective-C
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__weak ViewController *weakSelf = self;
dispatch_async(queue, ^{
__strong ViewController *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf // ...
});
}
dispatch_async(queue) { [unowned self] in
self.//...
}
}
To Swift from Objective-C
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
dispatch_queue_t queue = dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__weak ViewController *weakSelf = self;
dispatch_async(queue, ^{
__strong ViewController *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf // ...
});
}
dispatch_async(queue) { [weak self] in
if let strongSelf = self {
strongSelf.//...
}
}
}
To Swift from Objective-C
protocol HasTitle {
var title: String { get set }
func printTitle()
}
@protocol HasTitle <NSObject>
@property (copy, nonatomic) NSString *title;
- (void)printTitle;
@end
To Swift from Objective-C
protocol HasTitle {
var title: String { get set }
func printTitle()
}
@protocol HasTitle <NSObject>
@property (copy, nonatomic) NSString *title;
- (void)printTitle;
@end
struct Book: HasTitle {
var title: String
var pages: Int
func printTitle() {
print("Title: (title) ((pages) pages)")
}
}
struct DVD: HasTitle {
var title: String
var length: Int
func printTitle() {
print("Title: (title) ((length) minutes)")
}
}
To Swift from Objective-C
let book = Book(title: "It", pages: 1104)
let dvd = DVD(title: "It", length: 187)
let myCollection: [HasTitle] = [book, dvd]
for item in myCollection {
item.printTitle()
}
// Title: It (1104 pages)
// Title: It (187 minutes)
struct Book: HasTitle {
var title: String
var pages: Int
func printTitle() {
print("Title: (title) ((pages) pages)")
}
}
struct DVD: HasTitle {
var title: String
var length: Int
func printTitle() {
print("Title: (title) ((length) minutes)")
}
}
To Swift from Objective-C
let book = Book(title: "It", pages: 1104)
let dvd = DVD(title: "It", length: 187)
let myCollection: [HasTitle] = [book, dvd]
for item in myCollection {
item.printTitle()
}
To Swift from Objective-C
let book = Book(title: "It", pages: 1104)
let dvd = DVD(title: "It", length: 187)
let myCollection: [HasTitle] = [book, dvd]
for item in myCollection {
item.printTitle()
switch item {
case is Book:
print("has", (item as! Book).pages, "pages")
case is DVD:
print("is", (item as! DVD).length, "minutes")
default:
break
}
}
To Swift from Objective-C
let book = Book(title: "It", pages: 1104)
let dvd = DVD(title: "It", length: 187)
let myCollection: [HasTitle] = [book, dvd]
for item in myCollection {
item.printTitle()
if let book = item as? Book {
print("has", book.pages, "pages")
}
if let dvd = item as? DVD {
print("is", dvd.length, "minutes")
}
}
To Swift from Objective-C
struct Array<Element> // ...
struct Dictionary<Key: Hashable, Value> // ...
struct Set<Element: Hashable> // ...
To Swift from Objective-C
struct Array<Element> // ...
struct Dictionary<Key: Hashable, Value> // ...
struct Set<Element: Hashable> // ...
struct ItemHolder<T> {
var items: [T]
func randomItem() -> T {
let index = Int(arc4random_uniform(UInt32(items.count)))
return items[index]
}
}
To Swift from Objective-C
let numberHolder = ItemHolder(items: [1, 2, 3])
let objectA = SomeClass(title: "A")
let objectB = SomeClass(title: "B")
let objectC = SomeClass(title: "C")
let objectHolder = ItemHolder(items: [objectA, objectB, objectC])
numberHolder.randomItem() // 2
stringHolder.randomItem() // Neil
objectHolder.randomItem().title // A
func randomItemFromArray<T>(items: [T]) -> T {
let index = Int(arc4random_uniform(UInt32(items.count)))
return items[index]
}
let stringHolder = ItemHolder(items: ["Neil", "Geddy", “Alex"])
To Swift from Objective-C
• Access control
• Scopes
• Module
• File
• Levels
• Public
• Internal
• Private
To Swift from Objective-C
• Access control
• Public
• Highest level of accessibility
• Good for framework API
• Code available throughout defining module
• Available to other modules via import
To Swift from Objective-C
• Access control
• Internal
• Default for projects
• Code available throughout defining module
• Cannot be imported
To Swift from Objective-C
• Access control
• Private
• Default for playgrounds
• Code available only in defining source file
• Cannot be imported
To Swift from Objective-C

To Swift 2...and Beyond!

  • 1.
  • 2.
    About me • iOSdeveloper since 2010 • Swift since day 1 • Transitioning to Swift • RayWenderlich.com • CocoaConf • Wash U • Swift 2 Essential Training on lynda.com • Principal iOS Architect at Care Otter
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
    Who are you? •Doing iOS development? • For more than 1 year? • Swift? • Swift 2?
  • 16.
    What I’ll cover •To Swift from Objective-C • To Swift 2 • ...and Beyond! • What’s coming in Swift 2.2 and 3.0
  • 17.
    To Swift fromObjective-C Optionals Classes Functions & Closures Enumerations Reference Types Value Types Structures Integers Floating-Points Booleans Characters Strings Arrays Dictionaries Tuples
  • 18.
    To Swift fromObjective-C Value types are passed by copy Value Typex = y = xValue Type Value Type copy
  • 19.
    To Swift fromObjective-C Reference types are passed by reference x = y = xReference Type Reference Type
  • 20.
    To Swift fromObjective-C Objective-C Swift
  • 21.
    To Swift fromObjective-C NSString *greeting = @"Hello"; let greeting = "Hello"
  • 22.
    To Swift fromObjective-C NSString *greeting = @"Hello"; let greeting: String = "Hello"
  • 23.
  • 24.
    To Swift fromObjective-C NSMutableString *greeting = @"Hello"; var greeting = "Hello"
  • 25.
    To Swift fromObjective-C NSMutableString *greeting = var greeting = "Hello" greeting += ", world!"[greeting appendString:@", world!"]; [@"Hello" mutableCopy];
  • 26.
    To Swift fromObjective-C NSMutableString *greeting = var greeting = "Hello" [greeting appendString:@", world!"]; [@"Hello" mutableCopy]; greeting = greeting.stringByAppendingString(", world!")
  • 27.
    To Swift fromObjective-C NSMutableString *greeting = var greeting = "Hello" greeting += ", world!"[greeting appendString:@", world!"]; [@"Hello" mutableCopy]; NSLog(@"%@", greeting); // 2016-... Hello, world! NSLog("%@", greeting) // 2016-... Hello, world! NSLog(greeting) // 2016-... Hello, world! print(greeting) // Hello, world! print("Scott said: (greeting)")
  • 28.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Int // Int let two = 2 let negativeOne = -1
  • 29.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; let two: UInt = 2 // Intlet negativeOne = -1
  • 30.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; let two = 2 as UInt // Intlet negativeOne = -1
  • 31.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Intlet negativeOne = -1 let two: UInt = 2 let one = negativeOne + twoNSInteger one = negativeOne + two; ! error: ambiguous use of operator '+'
  • 32.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Intlet negativeOne = -1 let two: UInt = 2 NSInteger one = negativeOne + two; let one = negativeOne + Int(two)
  • 33.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Intlet negativeOne = -1 let two: UInt = 2 NSInteger one = negativeOne + two; let one = negativeOne + Int(two) let threePointOneFour: Float = 3.14CGFloat threePointOneFour = 3.14; let π = M_PI // Double, 3.141592653589793 let ! = "What's that smell?" NSString *greeting = @"Hello!"; let greeting = "Hello!" let a: Character = "a"char a = 'a'; BOOL thisMuchIs = let thisMuchIs =YES; true id anyObject = [NSObject new]; let anyObject: AnyObject = NSObject() let numberOne = NSNumber(integer: 1)
  • 34.
    To Swift fromObjective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Intlet negativeOne = -1 let two: UInt = 2 NSInteger one = negativeOne + two; let one = negativeOne + Int(two) let threePointOneFour = 3.14 // Doublelet threePointOneFour: Float = 3.14CGFloat threePointOneFour = 3.14; let π = M_PI // Double, 3.141592653589793 let ! = "What's that smell?" NSString *greeting = @"Hello!"; let greeting = "Hello!" let a: Character = "a"char a = 'a'; BOOL thisMuchIs = let thisMuchIs =YES; trueNO; id anyObject = [NSObject new]; let anyObject: AnyObject = NSObject() let numberOne = NSNumber(integer: 1) NSRange range = NSMakeRange(0, 5); let rangeInclusive = 0...5 let rangeExclusive = 0..<5
  • 35.
    To Swift fromObjective-C NSMutableString *greeting = var greeting = "Hello" greeting = nilgreeting = nil; [@"Hello" mutableCopy]; if (greeting) { // ... } ! error: nil cannot be assigned to type 'String'
  • 36.
    To Swift fromObjective-C NSMutableString *greeting = greeting = nilgreeting = nil; [@"Hello" mutableCopy]; if (greeting) { // ... } var greeting: String? = "Hello" if let greeting = greeting { // ... } greeting?.isEmpty greeting?.characters.first?.hashValue var dateOfBirth: NSDate! = NSDate(timeIntervalSince1970: 20581200) dateOfBirth.descriptionWithLocale(NSLocale. currentLocale()) print(greeting!.characters.first!)! error: unexpectedly found nil while unwrapping an Optional value
  • 37.
    To Swift fromObjective-C NSMutableString *greeting = greeting = nil; [@"Hello" mutableCopy]; if (greeting) { // ... } var greeting: String? = "Hello" if let greeting = greeting { // ... } greeting?.isEmpty greeting?.characters.first?.hashValue var dateOfBirth: NSDate! = NSDate(timeIntervalSince1970: 20581200) dateOfBirth.descriptionWithLocale(NSLocale. currentLocale()) print(greeting!.characters.first!) //greeting = nil
  • 38.
    To Swift fromObjective-C let letters = ["A", "B", "C"]NSArray *letters = @[@"A", @"B", @"C"];
  • 39.
    To Swift fromObjective-C NSArray *letters = @[@"A", @"B", @"C"]; let letters: [String] = ["A", "B", "C"]
  • 40.
    To Swift fromObjective-C NSArray *letters = @[@"A", @"B", @"C"]; let letters: Array<String> = ["A", "B", "C"]
  • 41.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSArray *letters = @[@"A", @"B", @"C"]; let numbers = [1: "One", 2: "Two", 3: "Three"] let letters = ["A", "B", "C"]
  • 42.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSArray *letters = @[@"A", @"B", @"C"]; let letters = ["A", "B", "C"] let numbers: [Int: String] = [1: "One", 2: "Two", 3: "Three"]
  • 43.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSArray *letters = @[@"A", @"B", @"C"]; let letters = ["A", "B", "C"] let numbers: Dictionary<Int, String> = [1: "One", 2: "Two", 3: "Three"]
  • 44.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSSet *uniqueValues = [NSSet setWithArray:@[@1, @2, @3, @1]]; print(uniqueValues) // [2, 3, 1] NSArray *letters = @[@"A", @"B", @"C"]; let uniqueValues: Set<Int> = [1, 2, 3, 1] let letters = ["A", "B", "C"] let numbers = [1: "One", 2: "Two", 3: "Three"] let httpResponse: = (200, "OK")
  • 45.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSSet *uniqueValues = [NSSet setWithArray:@[@1, @2, @3, @1]]; print(uniqueValues) // [2, 3, 1] NSArray *letters = @[@"A", @"B", @"C"]; let uniqueValues: Set<Int> = [1, 2, 3, 1] let letters = ["A", "B", "C"] let numbers = [1: "One", 2: "Two", 3: "Three"] let httpResponse: (Int, String) = (200, "OK")
  • 46.
    To Swift fromObjective-C NSDictionary *numbers = @{@1 : @"One", @2 : @"Two", @3 : @"Three"}; NSSet *uniqueValues = [NSSet setWithArray:@[@1, @2, @3, @1]]; print(uniqueValues) // [2, 3, 1] NSArray *letters = @[@"A", @"B", @"C"]; let uniqueValues: Set<Int> = [1, 2, 3, 1] let letters = ["A", "B", "C"] let numbers = [1: "One", 2: "Two", 3: "Three"] let httpResponse: (code: Int, text: String) = (code: 200, text: "OK") let httpResponseCode = httpResponse.code // 200 let httpResponseText = httpResponse.1 // OK func getHttpStatus() -> (code: Int, text: String) { return (200, "OK") }
  • 47.
    To Swift fromObjective-C let names = ["Moe", "Larry", "Curly"] if names.count > 0 { for name in names { print(name) } } NSArray *names = @[@"Moe", @"Larry", @"Curly"]; if (names.count > 0) { for (NSString *name in names) { NSLog(@"%@", name); } } func printNames() { guard names.count > 0 else { return } names.forEach { print($0) } }
  • 48.
    To Swift fromObjective-C NSInteger score = arc4random_uniform(101); switch (score) { case 100: // ... break; default: break; } let score = switch score { default: break } arc4random_uniform(101) case 99, 100: print("Top 2%") fallthrough case 95...100: print("Great job!") case let n where n % 2 == 0: print(n, "is even")
  • 49.
    To Swift fromObjective-C NSInteger score = arc4random_uniform(101); switch (score) { case 100: // ... break; default: break; } let score = switch score { default: break } 99 // Prints "Top 2%" // Prints "Great job!" case 99, 100: print("Top 2%") fallthrough case 95...100: print("Great job!") case let n where n % 2 == 0: print(n, "is even")
  • 50.
    To Swift fromObjective-C // In prepareForSegue:sender:… if let identifier = segue.identifier { switch (identifier, segue.destinationViewController) { } } case ("ShowControls", is ControlsViewController): // ... case ("ShowDetail", is DetailViewController): // ... default: break
  • 51.
    To Swift fromObjective-C - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; }
  • 52.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; }
  • 53.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; } + (void)doSomething { // ... } class func doSomething() { // ... }
  • 54.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; } + (void)doSomething { // ... } static func doSomething() { // ... }
  • 55.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; } + (void)doSomething { // ... } static func doSomething() { // ... }
  • 56.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; } + (void)doSomething { // ... } static func doSomething() -> Void { // ... }
  • 57.
    To Swift fromObjective-C func addThis(this: Int, andThat that: Int) -> Int { return this + that } - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; } + (void)doSomething { // ... } static func doSomething() { // ... } addThis(1, andThat: 2) func addThisAndThat(this: Int, _ that: Int) -> Int { return this + that } addThisAndThat(1, 2)
  • 58.
    To Swift fromObjective-C class SomeClass: NSObject {// SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end let title: String init(title: String) { self.title = title } }
  • 59.
    To Swift fromObjective-C class SomeClass: NSObject {// SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end let title: String init(title: String) { self.title = title } }
  • 60.
    To Swift fromObjective-C class SomeClass: NSObject {// SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end static var aStaticValue = 1 let title: String init(title: String) { self.title = title } }
  • 61.
    To Swift fromObjective-C // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end class SomeClass: NSObject { static var aStaticValue = 1 let title: String init(theTitle: String) { title = theTitle } }
  • 62.
    To Swift fromObjective-C // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end class SomeClass: NSObject { static var aStaticValue = 1 let title: String init(title: String) { self.title = title } }
  • 63.
    To Swift fromObjective-C SomeClass *someClass = [[SomeClass alloc] initWithTitle:@"A Mighty Instance"];
  • 64.
    To Swift fromObjective-C let someClass = SomeClass(title: "A Mighty Title")SomeClass *someClass = [SomeClass new]; someClass.title = @"A Mighty Instance";
  • 65.
    To Swift fromObjective-C SomeClass *someClass = [SomeClass new]; someClass.title = @"A Mighty Instance"; let someClass = SomeClass() error: missing argument for parameter 'title' in call !
  • 66.
    To Swift fromObjective-C // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end class SomeClass: NSObject { static var aStaticValue = 1 let title: String init(title: String) { self.title = title super.init() } }
  • 67.
    To Swift fromObjective-C // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end class SomeClass: NSObject { static var aStaticValue = 1 let title: String init(title: String) { super.init() self.title = title } } ! error: property 'self.title' not initialized at super.init call
  • 68.
    To Swift fromObjective-C // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end class SomeClass: NSObject { static var aStaticValue = 1 ? } var title: String
  • 69.
    To Swift fromObjective-C class SomeClass static var aStaticValue = 1 var title: String } // SomeClass.h #import <Foundation/Foundation.h> @interface SomeClass : NSObject @property (copy, nonatomic) NSString *title; - (instancetype)initWithTitle:(NSString *)title; @end // SomeClass.m #import "SomeClass.h" @implementation SomeClass - (instancetype)initWithTitle:(NSString *)title { if (self = [super init]) { self.title = title; return self; } return nil; } @end { ?
  • 70.
    To Swift fromObjective-C Properties Methods Subscripts Initializers Extensions Adopt Protocols Class ✓ ✓ ✓ ✓ ✓ ✓ Structure ✓ ✓ ✓ ✓ ✓ ✓ Enumeration ✓ ✓ ✓ ✓ ✓ ✓
  • 71.
    To Swift fromObjective-C struct Coordinate { CGFloat x; CGFloat y; CGFloat z; }; struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat }
  • 72.
    To Swift fromObjective-C struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; NSString *title; }; ! error: ARC forbids Objective-C objects in struct
  • 73.
    To Swift fromObjective-C struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat var title: String } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; // NSString *title; };
  • 74.
    To Swift fromObjective-C let coordinate = Coordinate(x: 0.0, y: 0.0, z: 0.0, title: "Origin") struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat var title: String } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; // NSString *title; }; struct Coordinate coordinate = {10.0, 10.0, 10.0};
  • 75.
    To Swift fromObjective-C let coordinate = Coordinate(x: 0.0, y: 0.0, z: 0.0, title: "Origin") enum Heading: Int { case North, South, East, West } struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat var title: String } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; // NSString *title; }; struct Coordinate coordinate = {10.0, 10.0, 10.0}; typedef NS_ENUM(NSInteger, Heading) { HeadingNorth, HeadingEast, HeadingSouth, HeadingWest };
  • 76.
    To Swift fromObjective-C let coordinate = Coordinate(x: 0.0, y: 0.0, z: 0.0, title: "Origin") struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat var title: String } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; // NSString *title; }; struct Coordinate coordinate = {10.0, 10.0, 10.0}; typedef NS_ENUM(NSInteger, Heading) { HeadingNorth, HeadingEast, HeadingSouth, HeadingWest }; enum Heading { case North, South, East, West }
  • 77.
    To Swift fromObjective-C let coordinate = Coordinate(x: 0.0, y: 0.0, z: 0.0, title: "Origin") let movement = Movement.North(distance: 20.0) struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat var title: String } struct Coordinate { CGFloat x; CGFloat y; CGFloat z; // NSString *title; }; struct Coordinate coordinate = {10.0, 10.0, 10.0}; typedef NS_ENUM(NSInteger, Heading) { HeadingNorth, HeadingEast, HeadingSouth, HeadingWest }; enum Heading { case North, South, East, West } enum Movement { case North(distance: Double) case South(distance: Double) case East(distance: Double) case West(distance: Double) }
  • 78.
    To Swift fromObjective-C - (NSString *)fullName { return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName]; } - (void)setTitle:(NSString *)title { NSLog(@"Old title: %@", _title); _title = title; } struct Person { let firstName: String let lastName: String } var fullName: String { return "(firstName) (lastName)" } var title: String { didSet { print("Old title: " + oldValue) } }
  • 79.
    To Swift fromObjective-C // ViewController+UITableViewDataSource.m #import "ViewController.h" @interface ViewController (UITableViewDataSource) @end // ViewController+UITableViewDataSource.m #import "ViewController+UITableViewDataSource.h" @implementation ViewController (UITableViewDataSource) - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; // ... return cell; } @end extension ViewController: UITableViewDataSource { func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! // ... return cell } }
  • 80.
    To Swift fromObjective-C @IBDesignable class DesignableView: UIView { } extension UIView { @IBInspectable var borderWidth: CGFloat { get { return layer.borderWidth } set { layer.borderWidth = newValue } } @IBInspectable var borderColor: UIColor? { get { return layer.borderColor != nil ? UIColor(CGColor: layer.borderColor!) : nil } set { layer.borderColor = newValue?.CGColor } } @IBInspectable var cornerRadius: CGFloat { get { return layer.cornerRadius } set { layer.masksToBounds = newValue != 0 layer.cornerRadius = newValue } } }
  • 81.
    To Swift fromObjective-C UIView.animateWithDuration(1.0, animations: { // ... }, completion: { print("Done!") }) [UIView animateWithDuration:1.0 animations:^{ // ... } completion:^(BOOL finished) { NSLog(@"Done!"); }]; (finished: Bool) in
  • 82.
    To Swift fromObjective-C UIView.animateWithDuration(1.0, animations: { // ... }, completion: { print("Done!") }) [UIView animateWithDuration:1.0 animations:^{ // ... } completion:^(BOOL finished) { NSLog(@"Done!"); }]; finished in
  • 83.
    To Swift fromObjective-C UIView.animateWithDuration(1.0, animations: { // ... }, completion: { print("Done!") }) [UIView animateWithDuration:1.0 animations:^{ // ... } completion:^(BOOL finished) { NSLog(@"Done!"); }]; UIView.animateWithDuration(1.0, animations: { // ... }) { _ in print("Done!") } finished in
  • 84.
    To Swift fromObjective-C UIView.animateWithDuration(1.0, animations: { // ... }, completion: { print("Done!") }) [UIView animateWithDuration:1.0 animations:^{ // ... } completion:^(BOOL finished) { NSLog(@"Done!"); }]; UIView.animateWithDuration(1.0, animations: { // ... }) { _ in print("Done!") } var fileContents = { // Some complex work return "..." }() finished in
  • 85.
    To Swift fromObjective-C override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); __weak ViewController *weakSelf = self; dispatch_async(queue, ^{ __strong ViewController *strongSelf = weakSelf; if (!strongSelf) { return; } [strongSelf // ... }); } dispatch_async(queue) { [unowned self] in self.//... } }
  • 86.
    To Swift fromObjective-C override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); __weak ViewController *weakSelf = self; dispatch_async(queue, ^{ __strong ViewController *strongSelf = weakSelf; if (!strongSelf) { return; } [strongSelf // ... }); } dispatch_async(queue) { [weak self] in if let strongSelf = self { strongSelf.//... } } }
  • 87.
    To Swift fromObjective-C protocol HasTitle { var title: String { get set } func printTitle() } @protocol HasTitle <NSObject> @property (copy, nonatomic) NSString *title; - (void)printTitle; @end
  • 88.
    To Swift fromObjective-C protocol HasTitle { var title: String { get set } func printTitle() } @protocol HasTitle <NSObject> @property (copy, nonatomic) NSString *title; - (void)printTitle; @end struct Book: HasTitle { var title: String var pages: Int func printTitle() { print("Title: (title) ((pages) pages)") } } struct DVD: HasTitle { var title: String var length: Int func printTitle() { print("Title: (title) ((length) minutes)") } }
  • 89.
    To Swift fromObjective-C let book = Book(title: "It", pages: 1104) let dvd = DVD(title: "It", length: 187) let myCollection: [HasTitle] = [book, dvd] for item in myCollection { item.printTitle() } // Title: It (1104 pages) // Title: It (187 minutes) struct Book: HasTitle { var title: String var pages: Int func printTitle() { print("Title: (title) ((pages) pages)") } } struct DVD: HasTitle { var title: String var length: Int func printTitle() { print("Title: (title) ((length) minutes)") } }
  • 90.
    To Swift fromObjective-C let book = Book(title: "It", pages: 1104) let dvd = DVD(title: "It", length: 187) let myCollection: [HasTitle] = [book, dvd] for item in myCollection { item.printTitle() }
  • 91.
    To Swift fromObjective-C let book = Book(title: "It", pages: 1104) let dvd = DVD(title: "It", length: 187) let myCollection: [HasTitle] = [book, dvd] for item in myCollection { item.printTitle() switch item { case is Book: print("has", (item as! Book).pages, "pages") case is DVD: print("is", (item as! DVD).length, "minutes") default: break } }
  • 92.
    To Swift fromObjective-C let book = Book(title: "It", pages: 1104) let dvd = DVD(title: "It", length: 187) let myCollection: [HasTitle] = [book, dvd] for item in myCollection { item.printTitle() if let book = item as? Book { print("has", book.pages, "pages") } if let dvd = item as? DVD { print("is", dvd.length, "minutes") } }
  • 93.
    To Swift fromObjective-C struct Array<Element> // ... struct Dictionary<Key: Hashable, Value> // ... struct Set<Element: Hashable> // ...
  • 94.
    To Swift fromObjective-C struct Array<Element> // ... struct Dictionary<Key: Hashable, Value> // ... struct Set<Element: Hashable> // ... struct ItemHolder<T> { var items: [T] func randomItem() -> T { let index = Int(arc4random_uniform(UInt32(items.count))) return items[index] } }
  • 95.
    To Swift fromObjective-C let numberHolder = ItemHolder(items: [1, 2, 3]) let objectA = SomeClass(title: "A") let objectB = SomeClass(title: "B") let objectC = SomeClass(title: "C") let objectHolder = ItemHolder(items: [objectA, objectB, objectC]) numberHolder.randomItem() // 2 stringHolder.randomItem() // Neil objectHolder.randomItem().title // A func randomItemFromArray<T>(items: [T]) -> T { let index = Int(arc4random_uniform(UInt32(items.count))) return items[index] } let stringHolder = ItemHolder(items: ["Neil", "Geddy", “Alex"])
  • 96.
    To Swift fromObjective-C • Access control • Scopes • Module • File • Levels • Public • Internal • Private
  • 97.
    To Swift fromObjective-C • Access control • Public • Highest level of accessibility • Good for framework API • Code available throughout defining module • Available to other modules via import
  • 98.
    To Swift fromObjective-C • Access control • Internal • Default for projects • Code available throughout defining module • Cannot be imported
  • 99.
    To Swift fromObjective-C • Access control • Private • Default for playgrounds • Code available only in defining source file • Cannot be imported
  • 100.
    To Swift fromObjective-C