SlideShare a Scribd company logo
...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 from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift from Objective-C
To Swift 2
println("Hello, world!")
To Swift 2
print("Hello, world!")
To Swift 2
print("Hello, world!")
print(1, 2, 3, "...") // 1 2 3 ...
print(1, 2, 3, separator: "-") // 1-2-3
print(1, 2, separator: "", terminator: "")
print(3)
// 123
let stockPrices = ["AAPL": 101.42]
print("(stockPrices["AAPL"])")
To Swift 2
let someCondition = true
func doSomething() {
if someCondition {
print("Success")
}
}
To Swift 2
let someCondition = true
func doSomething() {
guard someCondition else {
return
}
print("Success")
}
To Swift 2
let someCondition = true
func doSomething() {
guard someCondition else {
return
}
print("Success")
}
func getBirthdayFromDate(date: NSDate?) -> String {
guard let date = date else {
return ""
}
return date.descriptionWithLocale(NSLocale.currentLocale())
}
To Swift 2
let someCondition = true
func doSomething() {
guard someCondition else {
return
}
print("Success")
}
func getBirthdayFromDate(date: NSDate?) -> String {
defer {
print("This will always print")
}
guard let date = date else {
return nil
}
return date.descriptionWithLocale(NSLocale.currentLocale())
}
print(getBirthdayFromDate(nil))
// This will always print
//
To Swift 2
let someCondition = true
func doSomething() {
guard someCondition else {
return
}
print("Success")
}
func getBirthdayFromDate(date: NSDate?) -> String {
defer {
print("This will always print")
}
guard let date = date else {
return nil
}
return date.descriptionWithLocale(NSLocale.currentLocale())
}
print(getBirthdayFromDate(NSDate(timeIntervalSince1970: 20581200)))
// This will always print
// Thursday, August 27, 1970 at 12:00:00 AM Central Daylight Time
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
} catch {
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
}
print("Success!")
try testErrorHandling()
print("Uh oh:", error)
catch {
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
}
print("Success!")
try testErrorHandling()
catch Error.A {
print("Error A occurred")
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
}
print("Success!")
try testErrorHandling()
catch Error.A {
print("Error A occurred")
} catch let Error.B(code, function) {
print("Code:", code, "Function:", function)
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
}
print("Success!")
try testErrorHandling()
catch let Error.B(code, function) where code > 4 {
print("Code:", code, "Function:", function)
} catch {
print("Uh oh!")
}
catch Error.A {
print("Error A occurred")
}
let simulatedErrorA = true
let simulatedErrorB = true
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws {
}
guard simulatedErrorA == false else {
throw Error.A
}
guard simulatedErrorB == false else {
let code = arc4random_uniform(10)
throw Error.B(code: code, function: __FUNCTION__)
}
do {
}
print("Success!")
try testErrorHandling()
catch let Error.B(code, function) where code > 4 {
print("Code:", code, "Function:", function)
} catch {
print("Uh oh!")
}
catch Error.A {
print("Error A occurred")
}
try! testErrorHandling()
let simulatedErrorA = false
let simulatedErrorB = false
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws -> String {
guard simulatedErrorA == false else {
throw Error.A
}
return "Success"
}
do {
let success = try testErrorHandling()
print(success)
} catch {
print("Uh oh!")
}
if let success = try? testErrorHandling() {
// ...
}
let simulatedErrorA = false
let simulatedErrorB = false
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws -> String {
guard simulatedErrorA == false else {
throw Error.A
}
return "Success"
}
func performActionThatMightFail() {
do {
try testErrorHandling()
} catch {
print("Uh oh!")
}
}
let simulatedErrorA = false
let simulatedErrorB = false
To Swift 2
enum Error: ErrorType {
case A
case B(code: UInt32, function: String)
}
func testErrorHandling() throws -> String {
guard simulatedErrorA == false else {
throw Error.A
}
return "Success"
}
let simulatedErrorA = false
let simulatedErrorB = false
func performActionThatMightFail() throws {
try testErrorHandling()
}
do {
try performActionThatMightFail()
} catch {
// ...
}
To Swift 2
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseInOut | .Autoreverse, animations: { () -> Void in
// ...
}, completion: nil)
To Swift 2
UIView.animateWithDuration(1.0, delay: 0.0, options: nil, animations: { () -> Void in
// ...
}, completion: nil)
To Swift 2
UIView.animateWithDuration(1.0, delay: 0.0, options: [.CurveEaseInOut, .Autoreverse], animations: { () -> Void in
// ...
}, completion: nil)
To Swift 2
UIView.animateWithDuration(1.0, delay: 0.0, options: [.CurveEaseInOut, .Autoreverse], animations: { () -> Void in
// ...
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.0, options: [], animations: { () -> Void in
// ...
}, completion: nil)
To Swift 2
struct OptionSet: OptionSetType {
}
static let A = OptionSet(rawValue: 1 << 0)
static let B = OptionSet(rawValue: 1 << 1)
static let C = OptionSet(rawValue: 1 << 2)
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
let options: OptionSet = [.A, .B, .C]
if options.contains(.A) {
// ...
}
To Swift 2
struct OptionSet: OptionSetType {
}
static let A = OptionSet(rawValue: 1 << 0)
static let B = OptionSet(rawValue: 1 << 1)
static let C = OptionSet(rawValue: 1 << 2)
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
let options: OptionSet = [.A, .B, .C]
if options.contains([.A]) {
// ...
}
To Swift 2
struct OptionSet: OptionSetType {
}
static let A = OptionSet(rawValue: 1 << 0)
static let B = OptionSet(rawValue: 1 << 1)
static let C = OptionSet(rawValue: 1 << 2)
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
let options: OptionSet = [.A, .B, .C]
if options.contains([.A, .B]) {
// ...
}
To Swift 2
protocol Vehicular {
var passengerCapacity: Int { get }
}
extension Vehicular {
var passengerCapacity: Int {
return 4
}
}
protocol Drivable {
func adjustSpeedToMph(mph: Int)
}
extension Drivable {
func adjustSpeedToMph(mph: Int) {
print("Now traveling at (mph) mph")
}
}
struct Sedan: Vehicular, Drivable { }
let sedan = Sedan()
sedan.passengerCapacity // 4
sedan.adjustSpeedToMph(75) // Now traveling at 75 mph
To Swift 2
extension RawRepresentable where RawValue: IntegerType {
}
public protocol RawRepresentable {
typealias RawValue
public init?(rawValue: Self.RawValue)
public var rawValue: Self.RawValue { get }
}
To Swift 2
extension RawRepresentable where RawValue: IntegerType {
}
func next() -> Self? {
return Self(rawValue: self.rawValue + 1)
}
func previous() -> Self? {
return Self(rawValue: self.rawValue - 1)
}
To Swift 2
extension RawRepresentable where RawValue: IntegerType {
}
func next() -> Self? {
return Self(rawValue: self.rawValue + 1)
}
func previous() -> Self? {
return Self(rawValue: self.rawValue - 1)
}
enum Number: UInt {
case One = 1, Two, Three, Four, Five
}
let threeAfterTwo = Number(rawValue: 2)?.next()?.next()?.next() // Five
...and Beyond
To Swift 2...and Beyond!
let tuple1 = (1, "Two")
let tuple2 = (1, "Two")
tuple1.0 == tuple2.0 && tuple1.1 == tuple2.1 // true
...and Beyond: Swift 2.2
let tuple1 = (1, "Two")
let tuple2 = (1, "Two")
...and Beyond: Swift 2.2
tuple1 == tuple2 // true
func doSomethingWith(int: Int) {
// ...
}
func doSomethingWith(string: String) {
// ...
}
...and Beyond: Swift 2.2
let doer = doSomethingWith!
note: found this candidate
func doSomethingWith(int: Int) {
^
note: found this candidate
func doSomethingWith(string: String) {
^
func doSomethingWith(int: Int) {
// ...
}
func doSomethingWith(string: String) {
// ...
}
...and Beyond: Swift 2.2
let intDoer = doSomethingWith(_: Int)
let stringDoer = doSomethingWith(_: String)
...and Beyond: Swift 2.2
...and Beyond: Swift 2.2
...and Beyond: Swift 3.0
func contains(_: CGPoint) -> Bool
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
// ...
}
textView.text.trimming(.whitespaceAndNewlines)
...and Beyond: Swift 3.0
for var i = 0; i < 10; i++ {
print(i)
}
...and Beyond: Swift 3.0
func addLineItem(product: String, price: Double)(quantity: Int) -> String {
// ...
}
...and Beyond: Swift 3.0
func scaleScore(var score: Double) {
score *= 1.1
print(score)
}
scaleScore(studentScore) // 83.6
studentScore // 76.0
var studentScore = 76.0
...and Beyond: Swift 3.0
var studentScore = 76.0
func scaleScore(inout score: Double) {
score *= 1.1
}
scaleScore(&studentScore)
studentScore // 83.6
...and Beyond: Swift 3.0
var studentScore = 76.0
func scaleScore(inout score: Double) {
score *= 1.1
}
scaleScore(&studentScore)
studentScore // 83.6
if var someValue = someValue {
someValue = "Cadabra"
}
var someValue: String? = "Abra"
...and Beyond: Swift 3.0
var studentScore = 76.0
func scaleScore(inout score: Double) {
score *= 1.1
}
scaleScore(&studentScore)
studentScore // 83.6
var someValue: String? = "Abra"
if let someValue = someValue {
// ...
}
...and Beyond: Swift 3.0
NSNotificationCenter.defaultCenter().addObserver(self,
selector:
name: "SomethingDidChangeNotification",
object: nil)
"somethingDidChangeNotification:",
...and Beyond: Swift 3.0
NSNotificationCenter.defaultCenter().addObserver(self,
selector:
name: "SomethingDidChangeNotification",
object: nil)
let selector = Selector(ViewController.handleSomethingDidChangeNotification(_:))
selector,
Resources
• swift.org
• github.com/apple/swift-evolution
• swiftdoc.org
• bit.ly/SwiftEssentialTraining
(case sensitive)
• bit.ly/SwiftGuide
(case sensitive)
Thank you!
Scott Gardner
@scotteg
scotteg.com
careotter.com

More Related Content

To Swift 2...and Beyond!

  • 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
  • 7. GCC
  • 14. Swift
  • 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 from Objective-C Optionals Classes Functions & Closures Enumerations Reference Types Value Types Structures Integers Floating-Points Booleans Characters Strings Arrays Dictionaries Tuples
  • 18. To Swift from Objective-C Value types are passed by copy Value Typex = y = xValue Type Value Type copy
  • 19. To Swift from Objective-C Reference types are passed by reference x = y = xReference Type Reference Type
  • 20. To Swift from Objective-C Objective-C Swift
  • 21. To Swift from Objective-C NSString *greeting = @"Hello"; let greeting = "Hello"
  • 22. To Swift from Objective-C NSString *greeting = @"Hello"; let greeting: String = "Hello"
  • 24. To Swift from Objective-C NSMutableString *greeting = @"Hello"; var greeting = "Hello"
  • 25. To Swift from Objective-C NSMutableString *greeting = var greeting = "Hello" greeting += ", world!"[greeting appendString:@", world!"]; [@"Hello" mutableCopy];
  • 26. To Swift from Objective-C NSMutableString *greeting = var greeting = "Hello" [greeting appendString:@", world!"]; [@"Hello" mutableCopy]; greeting = greeting.stringByAppendingString(", world!")
  • 27. 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)")
  • 28. To Swift from Objective-C NSInteger negativeOne = -1; NSUInteger two = 2; // Int // Int let two = 2 let negativeOne = -1
  • 29. To Swift from Objective-C NSInteger negativeOne = -1; NSUInteger two = 2; let two: UInt = 2 // Intlet negativeOne = -1
  • 30. To Swift from Objective-C NSInteger negativeOne = -1; NSUInteger two = 2; let two = 2 as UInt // Intlet negativeOne = -1
  • 31. 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 '+'
  • 32. 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)
  • 33. 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)
  • 34. 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
  • 35. 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'
  • 36. 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
  • 37. 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
  • 38. To Swift from Objective-C let letters = ["A", "B", "C"]NSArray *letters = @[@"A", @"B", @"C"];
  • 39. To Swift from Objective-C NSArray *letters = @[@"A", @"B", @"C"]; let letters: [String] = ["A", "B", "C"]
  • 40. To Swift from Objective-C NSArray *letters = @[@"A", @"B", @"C"]; let letters: Array<String> = ["A", "B", "C"]
  • 41. 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"]
  • 42. 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"]
  • 43. 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"]
  • 44. 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")
  • 45. 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")
  • 46. 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") }
  • 47. 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) } }
  • 48. 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")
  • 49. 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")
  • 50. 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
  • 51. To Swift from Objective-C - (void)addThis:(NSInteger)this andThat:(NSInteger)that { return this + that; }
  • 52. 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; }
  • 53. 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() { // ... }
  • 54. 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() { // ... }
  • 55. 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() { // ... }
  • 56. 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 { // ... }
  • 57. 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)
  • 58. 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 } }
  • 59. 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 } }
  • 60. 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 } }
  • 61. 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 } }
  • 62. 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 } }
  • 63. To Swift from Objective-C SomeClass *someClass = [[SomeClass alloc] initWithTitle:@"A Mighty Instance"];
  • 64. To Swift from Objective-C let someClass = SomeClass(title: "A Mighty Title")SomeClass *someClass = [SomeClass new]; someClass.title = @"A Mighty Instance";
  • 65. 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 !
  • 66. 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() } }
  • 67. 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
  • 68. 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
  • 69. 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 { ?
  • 70. To Swift from Objective-C Properties Methods Subscripts Initializers Extensions Adopt Protocols Class ✓ ✓ ✓ ✓ ✓ ✓ Structure ✓ ✓ ✓ ✓ ✓ ✓ Enumeration ✓ ✓ ✓ ✓ ✓ ✓
  • 71. To Swift from Objective-C struct Coordinate { CGFloat x; CGFloat y; CGFloat z; }; struct Coordinate { var x: CGFloat var y: CGFloat var z: CGFloat }
  • 72. 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
  • 73. 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; };
  • 74. 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};
  • 75. 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 };
  • 76. 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 }
  • 77. 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) }
  • 78. 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) } }
  • 79. 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 } }
  • 80. 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 } } }
  • 81. 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
  • 82. 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
  • 83. 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
  • 84. 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
  • 85. 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.//... } }
  • 86. 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.//... } } }
  • 87. 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
  • 88. 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)") } }
  • 89. 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)") } }
  • 90. 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() }
  • 91. 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 } }
  • 92. 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") } }
  • 93. To Swift from Objective-C struct Array<Element> // ... struct Dictionary<Key: Hashable, Value> // ... struct Set<Element: Hashable> // ...
  • 94. 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] } }
  • 95. 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"])
  • 96. To Swift from Objective-C • Access control • Scopes • Module • File • Levels • Public • Internal • Private
  • 97. 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
  • 98. To Swift from Objective-C • Access control • Internal • Default for projects • Code available throughout defining module • Cannot be imported
  • 99. To Swift from Objective-C • Access control • Private • Default for playgrounds • Code available only in defining source file • Cannot be imported
  • 100. To Swift from Objective-C
  • 101. To Swift from Objective-C
  • 102. To Swift from Objective-C
  • 103. To Swift from Objective-C
  • 104. To Swift from Objective-C
  • 105. To Swift from Objective-C
  • 106. To Swift from Objective-C
  • 107. To Swift from Objective-C
  • 108. To Swift from Objective-C
  • 109. To Swift from Objective-C
  • 110. To Swift from Objective-C
  • 111. To Swift from Objective-C
  • 112. To Swift from Objective-C
  • 115. To Swift 2 print("Hello, world!") print(1, 2, 3, "...") // 1 2 3 ... print(1, 2, 3, separator: "-") // 1-2-3 print(1, 2, separator: "", terminator: "") print(3) // 123 let stockPrices = ["AAPL": 101.42] print("(stockPrices["AAPL"])")
  • 116. To Swift 2 let someCondition = true func doSomething() { if someCondition { print("Success") } }
  • 117. To Swift 2 let someCondition = true func doSomething() { guard someCondition else { return } print("Success") }
  • 118. To Swift 2 let someCondition = true func doSomething() { guard someCondition else { return } print("Success") } func getBirthdayFromDate(date: NSDate?) -> String { guard let date = date else { return "" } return date.descriptionWithLocale(NSLocale.currentLocale()) }
  • 119. To Swift 2 let someCondition = true func doSomething() { guard someCondition else { return } print("Success") } func getBirthdayFromDate(date: NSDate?) -> String { defer { print("This will always print") } guard let date = date else { return nil } return date.descriptionWithLocale(NSLocale.currentLocale()) } print(getBirthdayFromDate(nil)) // This will always print //
  • 120. To Swift 2 let someCondition = true func doSomething() { guard someCondition else { return } print("Success") } func getBirthdayFromDate(date: NSDate?) -> String { defer { print("This will always print") } guard let date = date else { return nil } return date.descriptionWithLocale(NSLocale.currentLocale()) } print(getBirthdayFromDate(NSDate(timeIntervalSince1970: 20581200))) // This will always print // Thursday, August 27, 1970 at 12:00:00 AM Central Daylight Time
  • 121. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) }
  • 122. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } let simulatedErrorA = true let simulatedErrorB = true
  • 123. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } catch { } let simulatedErrorA = true let simulatedErrorB = true
  • 124. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } print("Success!") try testErrorHandling() print("Uh oh:", error) catch { } let simulatedErrorA = true let simulatedErrorB = true
  • 125. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } print("Success!") try testErrorHandling() catch Error.A { print("Error A occurred") } let simulatedErrorA = true let simulatedErrorB = true
  • 126. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } print("Success!") try testErrorHandling() catch Error.A { print("Error A occurred") } catch let Error.B(code, function) { print("Code:", code, "Function:", function) } let simulatedErrorA = true let simulatedErrorB = true
  • 127. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } print("Success!") try testErrorHandling() catch let Error.B(code, function) where code > 4 { print("Code:", code, "Function:", function) } catch { print("Uh oh!") } catch Error.A { print("Error A occurred") } let simulatedErrorA = true let simulatedErrorB = true
  • 128. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws { } guard simulatedErrorA == false else { throw Error.A } guard simulatedErrorB == false else { let code = arc4random_uniform(10) throw Error.B(code: code, function: __FUNCTION__) } do { } print("Success!") try testErrorHandling() catch let Error.B(code, function) where code > 4 { print("Code:", code, "Function:", function) } catch { print("Uh oh!") } catch Error.A { print("Error A occurred") } try! testErrorHandling() let simulatedErrorA = false let simulatedErrorB = false
  • 129. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws -> String { guard simulatedErrorA == false else { throw Error.A } return "Success" } do { let success = try testErrorHandling() print(success) } catch { print("Uh oh!") } if let success = try? testErrorHandling() { // ... } let simulatedErrorA = false let simulatedErrorB = false
  • 130. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws -> String { guard simulatedErrorA == false else { throw Error.A } return "Success" } func performActionThatMightFail() { do { try testErrorHandling() } catch { print("Uh oh!") } } let simulatedErrorA = false let simulatedErrorB = false
  • 131. To Swift 2 enum Error: ErrorType { case A case B(code: UInt32, function: String) } func testErrorHandling() throws -> String { guard simulatedErrorA == false else { throw Error.A } return "Success" } let simulatedErrorA = false let simulatedErrorB = false func performActionThatMightFail() throws { try testErrorHandling() } do { try performActionThatMightFail() } catch { // ... }
  • 132. To Swift 2 UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseInOut | .Autoreverse, animations: { () -> Void in // ... }, completion: nil)
  • 133. To Swift 2 UIView.animateWithDuration(1.0, delay: 0.0, options: nil, animations: { () -> Void in // ... }, completion: nil)
  • 134. To Swift 2 UIView.animateWithDuration(1.0, delay: 0.0, options: [.CurveEaseInOut, .Autoreverse], animations: { () -> Void in // ... }, completion: nil)
  • 135. To Swift 2 UIView.animateWithDuration(1.0, delay: 0.0, options: [.CurveEaseInOut, .Autoreverse], animations: { () -> Void in // ... }, completion: nil) UIView.animateWithDuration(1.0, delay: 0.0, options: [], animations: { () -> Void in // ... }, completion: nil)
  • 136. To Swift 2 struct OptionSet: OptionSetType { } static let A = OptionSet(rawValue: 1 << 0) static let B = OptionSet(rawValue: 1 << 1) static let C = OptionSet(rawValue: 1 << 2) let rawValue: Int init(rawValue: Int) { self.rawValue = rawValue } let options: OptionSet = [.A, .B, .C] if options.contains(.A) { // ... }
  • 137. To Swift 2 struct OptionSet: OptionSetType { } static let A = OptionSet(rawValue: 1 << 0) static let B = OptionSet(rawValue: 1 << 1) static let C = OptionSet(rawValue: 1 << 2) let rawValue: Int init(rawValue: Int) { self.rawValue = rawValue } let options: OptionSet = [.A, .B, .C] if options.contains([.A]) { // ... }
  • 138. To Swift 2 struct OptionSet: OptionSetType { } static let A = OptionSet(rawValue: 1 << 0) static let B = OptionSet(rawValue: 1 << 1) static let C = OptionSet(rawValue: 1 << 2) let rawValue: Int init(rawValue: Int) { self.rawValue = rawValue } let options: OptionSet = [.A, .B, .C] if options.contains([.A, .B]) { // ... }
  • 139. To Swift 2 protocol Vehicular { var passengerCapacity: Int { get } } extension Vehicular { var passengerCapacity: Int { return 4 } } protocol Drivable { func adjustSpeedToMph(mph: Int) } extension Drivable { func adjustSpeedToMph(mph: Int) { print("Now traveling at (mph) mph") } } struct Sedan: Vehicular, Drivable { } let sedan = Sedan() sedan.passengerCapacity // 4 sedan.adjustSpeedToMph(75) // Now traveling at 75 mph
  • 140. To Swift 2 extension RawRepresentable where RawValue: IntegerType { } public protocol RawRepresentable { typealias RawValue public init?(rawValue: Self.RawValue) public var rawValue: Self.RawValue { get } }
  • 141. To Swift 2 extension RawRepresentable where RawValue: IntegerType { } func next() -> Self? { return Self(rawValue: self.rawValue + 1) } func previous() -> Self? { return Self(rawValue: self.rawValue - 1) }
  • 142. To Swift 2 extension RawRepresentable where RawValue: IntegerType { } func next() -> Self? { return Self(rawValue: self.rawValue + 1) } func previous() -> Self? { return Self(rawValue: self.rawValue - 1) } enum Number: UInt { case One = 1, Two, Three, Four, Five } let threeAfterTwo = Number(rawValue: 2)?.next()?.next()?.next() // Five
  • 145. let tuple1 = (1, "Two") let tuple2 = (1, "Two") tuple1.0 == tuple2.0 && tuple1.1 == tuple2.1 // true ...and Beyond: Swift 2.2
  • 146. let tuple1 = (1, "Two") let tuple2 = (1, "Two") ...and Beyond: Swift 2.2 tuple1 == tuple2 // true
  • 147. func doSomethingWith(int: Int) { // ... } func doSomethingWith(string: String) { // ... } ...and Beyond: Swift 2.2 let doer = doSomethingWith! note: found this candidate func doSomethingWith(int: Int) { ^ note: found this candidate func doSomethingWith(string: String) { ^
  • 148. func doSomethingWith(int: Int) { // ... } func doSomethingWith(string: String) { // ... } ...and Beyond: Swift 2.2 let intDoer = doSomethingWith(_: Int) let stringDoer = doSomethingWith(_: String)
  • 151. ...and Beyond: Swift 3.0 func contains(_: CGPoint) -> Bool func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) { // ... } textView.text.trimming(.whitespaceAndNewlines)
  • 152. ...and Beyond: Swift 3.0 for var i = 0; i < 10; i++ { print(i) }
  • 153. ...and Beyond: Swift 3.0 func addLineItem(product: String, price: Double)(quantity: Int) -> String { // ... }
  • 154. ...and Beyond: Swift 3.0 func scaleScore(var score: Double) { score *= 1.1 print(score) } scaleScore(studentScore) // 83.6 studentScore // 76.0 var studentScore = 76.0
  • 155. ...and Beyond: Swift 3.0 var studentScore = 76.0 func scaleScore(inout score: Double) { score *= 1.1 } scaleScore(&studentScore) studentScore // 83.6
  • 156. ...and Beyond: Swift 3.0 var studentScore = 76.0 func scaleScore(inout score: Double) { score *= 1.1 } scaleScore(&studentScore) studentScore // 83.6 if var someValue = someValue { someValue = "Cadabra" } var someValue: String? = "Abra"
  • 157. ...and Beyond: Swift 3.0 var studentScore = 76.0 func scaleScore(inout score: Double) { score *= 1.1 } scaleScore(&studentScore) studentScore // 83.6 var someValue: String? = "Abra" if let someValue = someValue { // ... }
  • 158. ...and Beyond: Swift 3.0 NSNotificationCenter.defaultCenter().addObserver(self, selector: name: "SomethingDidChangeNotification", object: nil) "somethingDidChangeNotification:",
  • 159. ...and Beyond: Swift 3.0 NSNotificationCenter.defaultCenter().addObserver(self, selector: name: "SomethingDidChangeNotification", object: nil) let selector = Selector(ViewController.handleSomethingDidChangeNotification(_:)) selector,
  • 160. Resources • swift.org • github.com/apple/swift-evolution • swiftdoc.org • bit.ly/SwiftEssentialTraining (case sensitive) • bit.ly/SwiftGuide (case sensitive)