Scott GardnerMobile Software Engineering Manager (iOS) at The Weather Company, an IBM Business à Veteran iOS App Architect / Developer, Author & Apple Certified Trainer
A three-part presentation on the Swift programming language:
• An introduction to Swift for Objective-C developers
• Changes in Swift 2
• What's coming in Swift 2.2 & 3.0
Scott GardnerMobile Software Engineering Manager (iOS) at The Weather Company, an IBM Business à Veteran iOS App Architect / Developer, Author & Apple Certified Trainer
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
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!")
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)
}
}
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
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 {
// ...
}
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 }
}