To Swift 2...and Beyond!

Scott Gardner
Scott GardnerMobile Software Engineering Manager (iOS) at The Weather Company, an IBM Business à Veteran iOS App Architect / Developer, Author & Apple Certified Trainer
...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
1 sur 161

Contenu connexe

En vedette(20)

A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
Giordano Scalzo104.7K vues
CSS Grid Layout for Topconf, LinzCSS Grid Layout for Topconf, Linz
CSS Grid Layout for Topconf, Linz
Rachel Andrew185K vues
Swift Programming LanguageSwift Programming Language
Swift Programming Language
Giuseppe Arici108.7K vues
iOS for Android Developers (with Swift)iOS for Android Developers (with Swift)
iOS for Android Developers (with Swift)
David Truxall11.7K vues
Seven Steps to an Effective Mobile App StrategySeven Steps to an Effective Mobile App Strategy
Seven Steps to an Effective Mobile App Strategy
Samsung Business USA7.3K vues
Migration from Swing to JavaFXMigration from Swing to JavaFX
Migration from Swing to JavaFX
Yuichi Sakuraba27K vues
2015 YEAR IN REVIEW: MOBILE2015 YEAR IN REVIEW: MOBILE
2015 YEAR IN REVIEW: MOBILE
Monika Mikowska18.3K vues
Scaling UberScaling Uber
Scaling Uber
C4Media33.8K vues
Build Features, Not AppsBuild Features, Not Apps
Build Features, Not Apps
Natasha Murashev389K vues
iOS Swift & OCR 玩文字辨識iOS Swift & OCR 玩文字辨識
iOS Swift & OCR 玩文字辨識
政斌 楊949 vues
Pair Programming demystifiedPair Programming demystified
Pair Programming demystified
Daftcode49K vues
Visualising Data with CodeVisualising Data with Code
Visualising Data with Code
Ri Liu32.2K vues
Big-tent UX (UX Camp West 2016)Big-tent UX (UX Camp West 2016)
Big-tent UX (UX Camp West 2016)
Peter Boersma48.6K vues
Crap. The Content Marketing Deluge.Crap. The Content Marketing Deluge.
Crap. The Content Marketing Deluge.
Velocity Partners6.5M vues

Similaire à To Swift 2...and Beyond!(20)

Plus de Scott Gardner(6)

SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
Scott Gardner582 vues
Reactive Programming with RxSwiftReactive Programming with RxSwift
Reactive Programming with RxSwift
Scott Gardner4.9K vues
Reactive programming with RxSwiftReactive programming with RxSwift
Reactive programming with RxSwift
Scott Gardner1.7K vues
The Great CALayer TourThe Great CALayer Tour
The Great CALayer Tour
Scott Gardner1.4K vues

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)