407 swift interoperability in depth
TRANSCRIPT
-
8/10/2019 407 Swift Interoperability in Depth
1/173
2014 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
#WWD
Swift Interoperability in Depth
Session 407Doug GregorEngineer, Swift Compiler Team
Tools
-
8/10/2019 407 Swift Interoperability in Depth
2/173
Introduction
Swift is a new language for Cocoa
Seamless interoperability with Objective-C
Focus on language-level interoperability
-
8/10/2019 407 Swift Interoperability in Depth
3/173
Roadmap
Working with Cocoa How Objective-C APIs look and feel in Swift
id and AnyObject
Bridging Core Cocoa Types
Subclassing Objective-C ClassesCF Interoperability
-
8/10/2019 407 Swift Interoperability in Depth
4/173
Working with Cocoa
-
8/10/2019 407 Swift Interoperability in Depth
5/173
Swift View of Objective-C APIs
Swift provides seamless access to Objective-C APIs
-
8/10/2019 407 Swift Interoperability in Depth
6/173
Swift View of Objective-C APIs
Swift provides seamless access to Objective-C APIs
Swift view of an Objective-C API is different from Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
7/173
Swift View of Objective-C APIs
Swift provides seamless access to Objective-C APIs
Swift view of an Objective-C API is different from Objective-C
Same Cocoa conventions and idioms
-
8/10/2019 407 Swift Interoperability in Depth
8/173
-
8/10/2019 407 Swift Interoperability in Depth
9/173
Properties
Objective-C@property NSDate *fileModificationDate;
-
8/10/2019 407 Swift Interoperability in Depth
10/173
Properties
Objective-C@property NSDate *fileModificationDate;
Swiftvar fileModificationDate: NSDate!
-
8/10/2019 407 Swift Interoperability in Depth
11/173
Implicitly Unwrapped Optionals
var fileModificationDate: NSDate !
-
8/10/2019 407 Swift Interoperability in Depth
12/173
Implicitly Unwrapped Optionals
var fileModificationDate: NSDate !
A value of class type in Swift is never nil
-
8/10/2019 407 Swift Interoperability in Depth
13/173
Implicitly Unwrapped Optionals
var fileModificationDate: NSDate !
A value of class type in Swift is never nil
Optional types generalize the notion of nil
-
8/10/2019 407 Swift Interoperability in Depth
14/173
Implicitly Unwrapped Optionals
var fileModificationDate: NSDate !
A value of class type in Swift is never nil
Optional types generalize the notion of nil
Objective-C does not have a notion of a never- nil pointer
-
8/10/2019 407 Swift Interoperability in Depth
15/173
-
8/10/2019 407 Swift Interoperability in Depth
16/173
Objective-C@property (readonly) NSString *fileType;
Mapping Objective-C Types to Swift
-
8/10/2019 407 Swift Interoperability in Depth
17/173
Objective-C@property (readonly) NSString *fileType;
Swiftvar fileType: String ! { get }
Mapping Objective-C Types to Swift
-
8/10/2019 407 Swift Interoperability in Depth
18/173
Objective-C Types in Swift
-
8/10/2019 407 Swift Interoperability in Depth
19/173
Objective-C- (NSString *)fileNameExtensionForType:(NSString *)typeName
saveOperation:(UIDocumentSaveOperation)saveOperation;
Methods
-
8/10/2019 407 Swift Interoperability in Depth
20/173
Objective-C- (NSString *)fileNameExtensionForType:(NSString *)typeName
saveOperation:(UIDocumentSaveOperation)saveOperation;
Swiftfunc fileNameExtensionForType(typeName: String!,
saveOperation: UIDocumentSaveOperation) -> String!
Methods
-
8/10/2019 407 Swift Interoperability in Depth
21/173
-
8/10/2019 407 Swift Interoperability in Depth
22/173
-
8/10/2019 407 Swift Interoperability in Depth
23/173
Objective-C- (void)saveToURL:(NSURL *)url
forSaveOperation:(UIDocumentSaveOperation)saveOperationcompletionHandler:(void (^)(BOOL success))completionHandler;
Methods
-
8/10/2019 407 Swift Interoperability in Depth
24/173
Objective-C- (void)saveToURL:(NSURL *)url
forSaveOperation:(UIDocumentSaveOperation)saveOperationcompletionHandler:(void (^)(BOOL success))completionHandler;
Swiftfunc saveToURL(url: NSURL!,
forSaveOperation saveOperation: UIDocumentSaveOperation, completionHandler: ((success: Bool) -> Void)!)
Methods
-
8/10/2019 407 Swift Interoperability in Depth
25/173
-
8/10/2019 407 Swift Interoperability in Depth
26/173
MethodsArgument labels and internal parameter names
Objective-C- (void)saveToURL:(NSURL *)url
forSaveOperation :(UIDocumentSaveOperation) saveOperation completionHandler:(void (^)(BOOL success))completionHandler;
Swiftfunc saveToURL(url: NSURL!,
forSaveOperation saveOperation : UIDocumentSaveOperation, completionHandler: ((success: Bool) -> Void)!)
-
8/10/2019 407 Swift Interoperability in Depth
27/173
Objective-C- (void)saveToURL:(NSURL *)url
forSaveOperation:(UIDocumentSaveOperation)saveOperationcompletionHandler:( void (^)(BOOL success) )completionHandler;
Swiftfunc saveToURL(url: NSURL!,forSaveOperation saveOperation: UIDocumentSaveOperation,
completionHandler: ((success: Bool) -> Void)! )
Blocks and closuresMethods
-
8/10/2019 407 Swift Interoperability in Depth
28/173
Swiftfunc saveToURL(url: NSURL!,
forSaveOperation saveOperation: UIDocumentSaveOperation, completionHandler: ((success: Bool) -> Void)!)
Methods
-
8/10/2019 407 Swift Interoperability in Depth
29/173
Swiftfunc saveToURL(url: NSURL!,
forSaveOperation saveOperation: UIDocumentSaveOperation, completionHandler: ((success: Bool) -> Void)!)
Trailing closure syntaxMethods
h d
-
8/10/2019 407 Swift Interoperability in Depth
30/173
Swiftfunc saveToURL(url: NSURL!,
forSaveOperation saveOperation: UIDocumentSaveOperation, completionHandler: ((success: Bool) -> Void)!)
Usage document.saveToURL(documentURL, saveOperation: UIDocumentSaveOperation.ForCreating) {
success inif success { } else { }
}
Trailing closure syntaxMethods
I i i li
-
8/10/2019 407 Swift Interoperability in Depth
31/173
Initializers
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
I i i li
-
8/10/2019 407 Swift Interoperability in Depth
32/173
Initializers
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
Swiftinit(fileURL url: NSURL!)
I i i li
-
8/10/2019 407 Swift Interoperability in Depth
33/173
Initializers
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
Swiftinit(fileURL url: NSURL!)
I iti li
-
8/10/2019 407 Swift Interoperability in Depth
34/173
Initializers
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
Swiftinit(fileURL url: NSURL!)
I iti li
-
8/10/2019 407 Swift Interoperability in Depth
35/173
Initializers
Objective-C- (instancetype)initWith FileURL :(NSURL *)url;
Swiftinit( fileURL url: NSURL!)
Creating Objects
-
8/10/2019 407 Swift Interoperability in Depth
36/173
Creating Objects
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
UIDocument *document = [[UIDocument alloc ] initWithFileURL :documentURL];
Creating Objects
-
8/10/2019 407 Swift Interoperability in Depth
37/173
Creating Objects
Objective-C- (instancetype)initWithFileURL:(NSURL *)url;
Swiftinit(fileURL url: NSURL!)
UIDocument *document = [[UIDocument alloc ] initWithFileURL :documentURL];
let document = UIDocument ( fileURL : documentURL)
Factory Methods
-
8/10/2019 407 Swift Interoperability in Depth
38/173
Factory Methods
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha;
Factory Methods
-
8/10/2019 407 Swift Interoperability in Depth
39/173
Factory Methods
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha; UIColor *color = [ UIColor colorWithRed :1 green :0.67 blue :0.04 alpha :0];
Factory Methods
-
8/10/2019 407 Swift Interoperability in Depth
40/173
Factory Methods
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha;
Swiftclass func colorWithRed(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> UIColor!
UIColor *color = [ UIColor colorWithRed :1 green :0.67 blue :0.04 alpha :0];
Factory Methods
-
8/10/2019 407 Swift Interoperability in Depth
41/173
Factory Methods
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha;
Swiftclass func colorWithRed(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> UIColor!
let color = UIColor.colorWithRed (1, green : 0.67, blue : 0.04, alpha : 0)
UIColor *color = [ UIColor colorWithRed :1 green :0.67 blue :0.04 alpha :0];
Factory Methods as Initializers
-
8/10/2019 407 Swift Interoperability in Depth
42/173
Factory Methods as Initializers
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha;
Swift
UIColor *color = [UIColor colorWithRed:1 green:0.67 blue:0.04 alpha:0];
init ( red : CGFloat, green : CGFloat, blue : CGFloat, alpha : CGFloat)
Factory Methods as Initializers
-
8/10/2019 407 Swift Interoperability in Depth
43/173
Factory Methods as Initializers
Objective-C+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green
blue:(CGFloat)blue alpha:(CGFloat)alpha;
Swift
let color = UIColor ( red : 1, green : 0.67, blue : 0.04, alpha : 0)
UIColor *color = [UIColor colorWithRed:1 green:0.67 blue:0.04 alpha:0];
init ( red : CGFloat, green : CGFloat, blue : CGFloat, alpha : CGFloat)
Enums
-
8/10/2019 407 Swift Interoperability in Depth
44/173
Enums
Objective-Ctypedef NS_ENUM(NSInteger, UIDocumentSaveOperation) { UIDocumentSaveForCreating, UIDocumentSaveForOverwriting};
Enums
-
8/10/2019 407 Swift Interoperability in Depth
45/173
Enums
Objective-Ctypedef NS_ENUM(NSInteger, UIDocumentSave Operation) { UIDocumentSave ForCreating, UIDocumentSave ForOverwriting};
Enums
-
8/10/2019 407 Swift Interoperability in Depth
46/173
Enums
Objective-Ctypedef NS_ENUM(NSInteger, UIDocumentSaveOperation) { UIDocumentSaveForCreating, UIDocumentSaveForOverwriting};
Swiftenum UIDocumentSaveOperation : Int { case ForCreating case ForOverwriting}
-
8/10/2019 407 Swift Interoperability in Depth
47/173
Usage let ext = document.fileNameExtensionForType("public.presentation",
saveOperation:
Swiftenum UIDocumentSaveOperation : Int { case ForCreating case ForOverwriting}
Using Enums
-
8/10/2019 407 Swift Interoperability in Depth
48/173
Usage let ext = document.fileNameExtensionForType("public.presentation",
saveOperation:
Using Enums
.ForCreating)UIDocumentSaveOperation
Swiftenum UIDocumentSaveOperation : Int { case ForCreating case ForOverwriting}
-
8/10/2019 407 Swift Interoperability in Depth
49/173
NSError
-
8/10/2019 407 Swift Interoperability in Depth
50/173
Objective-C- (id)contentsForType:(NSString *)typeName error:( NSError ** )outError;
S o
NSError
-
8/10/2019 407 Swift Interoperability in Depth
51/173
Objective-C- (id)contentsForType:(NSString *)typeName error:( NSError ** )outError;
Swiftfunc contentsForType(typeName: String!, error: NSErrorPointer ) -> AnyObject!
-
8/10/2019 407 Swift Interoperability in Depth
52/173
Using NSError
-
8/10/2019 407 Swift Interoperability in Depth
53/173
g
Swiftfunc contentsForType(typeName: String!, error: NSErrorPointer) -> AnyObject!
Using NSError
-
8/10/2019 407 Swift Interoperability in Depth
54/173
g
Swiftfunc contentsForType(typeName: String!, error: NSErrorPointer) -> AnyObject!
Usage var error: NSError? if let contents = document.contentsForType("public.presentation",
error: &error ) {
// use the contents
}
-
8/10/2019 407 Swift Interoperability in Depth
55/173
-
8/10/2019 407 Swift Interoperability in Depth
56/173
Modernizing Your Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
57/173
These rules apply to all Objective-C APIs imported into SwiftSwift benefits greatly from modern Objective-C:
Properties
instancetype
NS_ENUM / NS_OPTIONS
NS_DESIGNATED_INITIALIZER
Modernizing Your Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
58/173
These rules apply to all Objective-C APIs imported into SwiftSwift benefits greatly from modern Objective-C:
Properties
instancetype
NS_ENUM / NS_OPTIONS
NS_DESIGNATED_INITIALIZER
Modernizing Your Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
59/173
These rules apply to all Objective-C APIs imported into SwiftSwift benefits greatly from modern Objective-C:
Properties
instancetype
NS_ENUM / NS_OPTIONS
NS_DESIGNATED_INITIALIZER
-
8/10/2019 407 Swift Interoperability in Depth
60/173
id and AnyObject
id in Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
61/173
Upcasts
id object = [[NSURL alloc] initWithString:@" http://developer.apple.com "]; object = view.superview;
id in Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
62/173
Upcasts
id object = [[NSURL alloc] initWithString:@" http://developer.apple.com "]; object = view.superview;
Message sends [object removeFromSuperview];
id in Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
63/173
Upcasts
id object = [[NSURL alloc] initWithString:@" http://developer.apple.com "]; object = view.superview;
Message sends [object removeFromSuperview];
Subscriptingid date = object[@"date"];
AnyObject: An Object of Any Type
-
8/10/2019 407 Swift Interoperability in Depth
64/173
Upcasts
id object = [[NSURL alloc] initWithString:@" http://developer.apple.com "]; object = view.superview;
Message sends [object removeFromSuperview];
Subscriptingid date = object[@"date"];
AnyObject: An Object of Any Type
-
8/10/2019 407 Swift Interoperability in Depth
65/173
Upcasts
var object: AnyObject = NSURL(string: " http://developer.apple.com ") object = view.superview
Message sends [object removeFromSuperview];
Subscriptingid date = object[@"date"];
AnyObject: An Object of Any Type
-
8/10/2019 407 Swift Interoperability in Depth
66/173
Upcasts
var object: AnyObject = NSURL(string: " http://developer.apple.com ") object = view.superview
Message sends object.removeFromSuperview()
Subscriptingid date = object[@"date"];
AnyObject: An Object of Any Type
-
8/10/2019 407 Swift Interoperability in Depth
67/173
Upcasts
var object: AnyObject = NSURL(string: " http://developer.apple.com ") object = view.superview
Message sends object.removeFromSuperview()
Subscriptinglet date = object["date"]
-
8/10/2019 407 Swift Interoperability in Depth
68/173
respondsToSelector Idiom
-
8/10/2019 407 Swift Interoperability in Depth
69/173
Messaging id or AnyObject can result in unrecognized selector failures
[object removeFromSuperview];
respondsToSelector idiom to test the presence of a method if ([object respondsToSelector :@selector(removeFromSuperview)]) {
[object removeFromSuperview];}
Checking the Presence of a Method
-
8/10/2019 407 Swift Interoperability in Depth
70/173
A method of AnyObject is optionalobject.removeFromSuperview ()
Checking the Presence of a Method
-
8/10/2019 407 Swift Interoperability in Depth
71/173
A method of AnyObject is optionalobject.removeFromSuperview
Chaining ? folds the respondsToSelector check into the call
?()
-
8/10/2019 407 Swift Interoperability in Depth
72/173
Downcasting AnyObject
-
8/10/2019 407 Swift Interoperability in Depth
73/173
AnyObject does not implicitly downcastlet view: UIView = object // error : AnyObject cannot be implicitly downcast
Downcasting AnyObject
-
8/10/2019 407 Swift Interoperability in Depth
74/173
AnyObject does not implicitly downcastlet view: UIView = object
as operator forces the downcastlet view
// error : AnyObject cannot be implicitly downcast
= object as UIView
Downcasting AnyObject
-
8/10/2019 407 Swift Interoperability in Depth
75/173
AnyObject does not implicitly downcastlet view: UIView = object
as operator forces the downcastlet view
as? operator performs a conditional downcastif let view = object as? UIView { // view is a UIView }
// error : AnyObject cannot be implicitly downcast
= object as UIView
Protocols
-
8/10/2019 407 Swift Interoperability in Depth
76/173
Objective-C@protocol UITableViewDataSource@optional- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;@required- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section;@end
Protocols
-
8/10/2019 407 Swift Interoperability in Depth
77/173
Objective-C@protocol UITableViewDataSource@optional- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;@required- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section;@end
Swift@objc protocol UITableViewDataSource : NSObjectProtocol { func tableView(tableView: UITableView, numberOfRowsInSection: Int) -> Int @optional func numberOfSectionsInTableView(tableView: UITableView) -> Int}
Protocols
-
8/10/2019 407 Swift Interoperability in Depth
78/173
Objective-C@protocol UITableViewDataSource@optional- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;@required- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section;@end
Swift@objc protocol UITableViewDataSource : NSObjectProtocol { func tableView(tableView: UITableView, numberOfRowsInSection: Int) -> Int @optional func numberOfSectionsInTableView(tableView: UITableView) -> Int}
Protocols
-
8/10/2019 407 Swift Interoperability in Depth
79/173
Objective-C@protocol UITableViewDataSource< NSObject >@optional- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;@required- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section;@end
Swift@objc protocol UITableViewDataSource : NSObjectProtocol {
func tableView(tableView: UITableView, numberOfRowsInSection: Int) -> Int @optional func numberOfSectionsInTableView(tableView: UITableView) -> Int}
Protocol Types
-
8/10/2019 407 Swift Interoperability in Depth
80/173
Objective-C@property id dataSource;
Protocol Types
-
8/10/2019 407 Swift Interoperability in Depth
81/173
Objective-C@property id dataSource;
Swiftvar dataSource: UITableViewDataSource !
Testing Protocol Conformance
-
8/10/2019 407 Swift Interoperability in Depth
82/173
Downcast via as? to protocol type if let dataSource = object as? UITableViewDataSource { let rowsInFirstSection = dataSource.tableView(tableView, numberOfRowsInSection: 0)}
Protocol Types
-
8/10/2019 407 Swift Interoperability in Depth
83/173
Objective-C@property id dataSource;
Swiftvar dataSource: UITableViewDataSource!
@property id delegate;
var delegate: protocol
Number of Rows in the Last Section
-
8/10/2019 407 Swift Interoperability in Depth
84/173
if let dataSource = object as? UITableViewDataSource {var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableViewlastSection = numSections - 1
(tableView)
Optional Methods in Protocols
-
8/10/2019 407 Swift Interoperability in Depth
85/173
if let dataSource = object as? UITableViewDataSource {var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableViewlastSection = numSections - 1
(tableView)
Optional Methods in Protocols
-
8/10/2019 407 Swift Interoperability in Depth
86/173
if let dataSource = object as? UITableViewDataSource {var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableViewlastSection = numSections - 1
(tableView)// error : method is optional
Optional Methods in Protocols
-
8/10/2019 407 Swift Interoperability in Depth
87/173
Use the chaining ? operatorif let dataSource = object as? UITableViewDataSource {
var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableViewlastSection = numSections - 1
(tableView)
Optional Methods in Protocols
-
8/10/2019 407 Swift Interoperability in Depth
88/173
Use the chaining ? operatorif let dataSource = object as? UITableViewDataSource {
var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableView if
}lastSection = numSections - 1
(tableView)?
Optional Methods in Protocols
-
8/10/2019 407 Swift Interoperability in Depth
89/173
Use the chaining ? operatorif let dataSource = object as? UITableViewDataSource {
var lastSection = 0
let rowsInLastSection = dataSource.tableView(tableView, numberOfRowsInSection: lastSection)
}
let numSections = dataSource.numberOfSectionsInTableView if
}lastSection = numSections - 1
(tableView)?
Optionals and Safety
-
8/10/2019 407 Swift Interoperability in Depth
90/173
Optionals and Safety
-
8/10/2019 407 Swift Interoperability in Depth
91/173
AnyObject is Swifts equivalent to id Similar functionality, more safe by default AnyClass is Swifts equivalent to Class
Optionals and Safety
-
8/10/2019 407 Swift Interoperability in Depth
92/173
AnyObject is Swifts equivalent to id Similar functionality, more safe by default AnyClass is Swifts equivalent to Class
Optionals used throughout the language to represent dynamic checks as? for safe downcasting, protocol conformance checking
Optionals when referring to methods that may not be available if let and chaining ? make optionals easy to use
-
8/10/2019 407 Swift Interoperability in Depth
93/173
Bridging Core Cocoa Types
Native Strings, Arrays, Dictionaries
-
8/10/2019 407 Swift Interoperability in Depth
94/173
One set of general-purpose native value types Safe by default
Predictable performance
Typed collections support items of any type
Bridged to Cocoa NSString , NSArray , NSDictionary
Native String Type
-
8/10/2019 407 Swift Interoperability in Depth
95/173
String is an efficient, Unicode-compliant string type
Flexible, efficient, high-level APIs for string manipulation
Value semantics
Native String Type
-
8/10/2019 407 Swift Interoperability in Depth
96/173
String is an efficient, Unicode-compliant string type
Flexible, efficient, high-level APIs for string manipulation
Value semanticsvar s1 = "Hello"var s2 = s1s1 += " Swiftprintln(s1)Hello Swiftprintln(s2)Hello
Characters
-
8/10/2019 407 Swift Interoperability in Depth
97/173
Iteration over a string produces characters let dog = "Dog! ! "for c in dog { // c is inferred as Character println(c)}
Characters
-
8/10/2019 407 Swift Interoperability in Depth
98/173
Iteration over a string produces characters let dog = "Dog! ! "for c in dog { // c is inferred as Character println(c)}
Dog! !
Characters and Code Points
-
8/10/2019 407 Swift Interoperability in Depth
99/173
Unicode characters cannot be efficiently encoded as fixed-width entities
Characters and Code Points
-
8/10/2019 407 Swift Interoperability in Depth
100/173
Unicode characters cannot be efficiently encoded as fixed-width entities Correct use of UTF-8 or UTF-16 requires deep knowledge of Unicode
Characters and Code Points
-
8/10/2019 407 Swift Interoperability in Depth
101/173
Unicode characters cannot be efficiently encoded as fixed-width entities Correct use of UTF-8 or UTF-16 requires deep knowledge of Unicode
Low-level operations ( length , characterAtIndex ) are not provided by String
Characters and Code Points
-
8/10/2019 407 Swift Interoperability in Depth
102/173
Unicode characters cannot be efficiently encoded as fixed-width entities Correct use of UTF-8 or UTF-16 requires deep knowledge of Unicode
Low-level operations ( length , characterAtIndex ) are not provided by String
countElements can be used to count the number of characters let dog = "Dog! ! "
println("There are \( countElements(dog) ) characters in `\(dog)")
Characters and Code Points
-
8/10/2019 407 Swift Interoperability in Depth
103/173
Unicode characters cannot be efficiently encoded as fixed-width entities Correct use of UTF-8 or UTF-16 requires deep knowledge of Unicode
Low-level operations ( length , characterAtIndex ) are not provided by String
countElements can be used to count the number of characters let dog = "Dog! ! "
println("There are \( countElements(dog) ) characters in `\(dog)")
// There are 5 characters in `Dog! !
Code Points
-
8/10/2019 407 Swift Interoperability in Depth
104/173
UTF-16 is available via a property
for codePoint in dog.utf16 { // codePoint is inferred as UInt16 // } print("There are \( countElements(dog.utf16) ) UTF-16 code points in `\(dog)")
Code Points
-
8/10/2019 407 Swift Interoperability in Depth
105/173
UTF-16 is available via a property
for codePoint in dog.utf16 { // codePoint is inferred as UInt16 // } print("There are \( countElements(dog.utf16) ) UTF-16 code points in `\(dog)")
// There are 6 UTF-16 code points in `Dog! !
String and NSString
-
8/10/2019 407 Swift Interoperability in Depth
106/173
Foundation NSString APIs are available on Stringlet fruits = "apple;banana;cherry".componentsSeparatedByString(";")
String and NSString
-
8/10/2019 407 Swift Interoperability in Depth
107/173
Foundation NSString APIs are available on Stringlet fruits = "apple;banana;cherry".componentsSeparatedByString(";")
// inferred as String[]
String and NSString
-
8/10/2019 407 Swift Interoperability in Depth
108/173
Foundation NSString APIs are available on Stringlet fruits = "apple;banana;cherry".componentsSeparatedByString(";")
Cast to NSString to access properties and methods on NSString categories ("Welcome to WWDC 2014" as NSString ).myNSStringMethod()
// inferred as String[]
String and NSString
-
8/10/2019 407 Swift Interoperability in Depth
109/173
Foundation NSString APIs are available on Stringlet fruits = "apple;banana;cherry".componentsSeparatedByString(";")
Cast to NSString to access properties and methods on NSString categories ("Welcome to WWDC 2014" as NSString ).myNSStringMethod()
Extend String with your method
extension String { func myStringMethod() -> String { }
}
// inferred as String[]
NSArray Bridges to Array of AnyObject
-
8/10/2019 407 Swift Interoperability in Depth
110/173
Objective-C@property NSArray *toolbarItems;
NSArray Bridges to Array of AnyObject
-
8/10/2019 407 Swift Interoperability in Depth
111/173
Objective-C@property NSArray *toolbarItems;
Swiftvar toolbarItems: AnyObject[] !
Upcasting Arrays
-
8/10/2019 407 Swift Interoperability in Depth
112/173
An array T[] can be assigned to an AnyObject[]let myToolbarItems: UIBarButtonItem[] = [item1, item2, item3]controller.toolbarItems = myToolbarItems
Downcasting Arrays
-
8/10/2019 407 Swift Interoperability in Depth
113/173
Iteration over an AnyObject[] produces AnyObject values for object: AnyObject in viewController.toolbarItems { let item = object as UIBarButtonItem // }
Downcasting Arrays
-
8/10/2019 407 Swift Interoperability in Depth
114/173
Iteration over an AnyObject[] produces AnyObject values for object: AnyObject in viewController.toolbarItems { let item = object as UIBarButtonItem // }
Can downcast AnyObject[] to an array of a specific type for item in viewController.toolbarItems as UIBarButtonItem[] {
// }
Array BridgingUnder the Hood
-
8/10/2019 407 Swift Interoperability in Depth
115/173
Swift array has two representations
T[]
Array BridgingUnder the Hood
-
8/10/2019 407 Swift Interoperability in Depth
116/173
Swift array has two representations
Native0 1 2 3 4 5length capacity 6
T[]
Array BridgingUnder the Hood
-
8/10/2019 407 Swift Interoperability in Depth
117/173
Swift array has two representations
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
Array BridgingUnder the Hood
-
8/10/2019 407 Swift Interoperability in Depth
118/173
Swift array has two representations
Array methods manage the representation internally
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
Array BridgingUnder the Hood
-
8/10/2019 407 Swift Interoperability in Depth
119/173
Swift array has two representations
Array methods manage the representation internally
Bridging converts between NSArray and a Swift array
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
NSArray Swift Array Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
120/173
Returning an NSArray * from an Objective-C method to Swiftlet items: AnyObject[] = viewController.toolbarItems
NSArray Swift Array Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
121/173
Returning an NSArray * from an Objective-C method to Swiftlet items: AnyObject[] = viewController.toolbarItems
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
NSArray Swift Array Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
122/173
Returning an NSArray * from an Objective-C method to Swiftlet items: AnyObject[] = viewController.toolbarItems
Calls copy() to ensure the array wont change underneath us
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
NSArray Swift Array Bridging
*
"
-
8/10/2019 407 Swift Interoperability in Depth
123/173
Returning an NSArray * from an Objective-C method to Swiftlet items: AnyObject[] = viewController.toolbarItems
Calls copy() to ensure the array wont change underneath us For immutable NSArray s, this operation is trivial
NSArray object
Native
Cocoa
0 1 2 3 4 5length capacity 6
T[]
P i S if Obj i C h d i SA *
T[] NSArray Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
124/173
Passing a Swift array to an Objective-C method expecting an NSArray *viewController.toolbarItems = myToolbarItems
P i T[] Obj i C h d i NSA *
T[] NSArray Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
125/173
isa
Passing a T[] to an Objective-C method expecting an NSArray*
viewController.toolbarItems = myToolbarItems
NSArray object
Native
Cocoa
T[]
0 1 2 3 4 5length capacity 6
P i T[] t Obj ti C th d ti NSA *
T[] NSArray Bridging"
-
8/10/2019 407 Swift Interoperability in Depth
126/173
isa
Passing a T[] to an Objective-C method expecting an NSArray*
viewController.toolbarItems = myToolbarItems
Native array representation isa NSArray, optimized
NSArray object
Native
Cocoa
T[]
0 1 2 3 4 5length capacity 6
-
8/10/2019 407 Swift Interoperability in Depth
127/173
Subclassing Objective-C Classes
Swift Objects Are Objective-C Objects
All Swift classes are id compatible
-
8/10/2019 407 Swift Interoperability in Depth
128/173
All Swift classes are id compatible
Same layout as an Objective-C class Same basic infrastructure (retain/release/class/etc.)
Swift Objects Are Objective-C Objects
All Swift classes are id compatible
-
8/10/2019 407 Swift Interoperability in Depth
129/173
All Swift classes are id compatible
Same layout as an Objective-C class Same basic infrastructure (retain/release/class/etc.)
Inherit from an Objective-C class to make your class directly visible in Objective-Cclass MyDocument : UIDocument { var items: String[] = []}
Overriding Methods
overridekeyword required when overriding a method
-
8/10/2019 407 Swift Interoperability in Depth
130/173
override keyword required when overriding a method
override func handleError(error: NSError!, userInteractionPermitted: Bool) { // customized behavior super.handleError(error,
userInteractionPermitted: userInteractionPermitted)}
Overriding Properties
Override the property itself, not the getter or setter
-
8/10/2019 407 Swift Interoperability in Depth
131/173
Override the property itself, not the getter or setter
override var description: String {return "MyDocument containing \(items)"
}
-
8/10/2019 407 Swift Interoperability in Depth
132/173
Swift
Your Swift Class
-
8/10/2019 407 Swift Interoperability in Depth
133/173
class MyDocument : UIDocument { var items: String[] = []
override func handleError(error: NSError, userInteractionPermitted: Bool)
override var description: String
override func contentsForType(typeName: String!, error: NSErrorPointer)-> AnyObject!
}
Objective-C
Your Swift Classin Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
134/173
j
SWIFT_CLASS("_TtC5MyApp10MyDocument")@interface MyDocument : UIDocument @property (nonatomic) NSArray *items; - (void)handleError:(NSError *)error
userInteractionPermitted:(BOOL)userInteractionPermitted;
@property (nonatomic, readonly) NSString *description; - (id)contentsForType:(NSString *)typeName error:(NSError **)outError;@end
-
8/10/2019 407 Swift Interoperability in Depth
135/173
Objective-C
Your Swift Classin Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
136/173
SWIFT_CLASS("_TtC5MyApp10MyDocument")@interface MyDocument : UIDocument @property (nonatomic) NSArray *items; - (void)handleError:(NSError *)error
userInteractionPermitted:(BOOL)userInteractionPermitted;
@property (nonatomic, readonly) NSString *description; - (id)contentsForType:(NSString *)typeName error:(NSError **)outError;@end
// Swift:var items: String[] = []
Objective-C
Your Swift Classin Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
137/173
SWIFT_CLASS(" _TtC5MyApp10MyDocument ") @interface MyDocument : UIDocument @property (nonatomic) NSArray *items; - (void)handleError:(NSError *)error
userInteractionPermitted:(BOOL)userInteractionPermitted;
@property (nonatomic, readonly) NSString *description; - (id)contentsForType:(NSString *)typeName error:(NSError **)outError;@end
Objective-C
Your Swift Classin Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
138/173
SWIFT_CLASS(" _TtC5MyApp10MyDocument ") @interface MyDocument : UIDocument @property (nonatomic) NSArray *items; - (void)handleError:(NSError *)error
userInteractionPermitted:(BOOL)userInteractionPermitted;
@property (nonatomic, readonly) NSString *description; - (id)contentsForType:(NSString *)typeName error:(NSError **)outError;@end
// usually written MyApp.MyDocume
Limitations of Objective-C
Swift has advanced features that arent expressible in Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
139/173
Tuples
Generics Enums and structs
func myGenericMethod(x: T) -> (String, String) { }
Limitations of Objective-C
Swift has advanced features that arent expressible in Objective-C
-
8/10/2019 407 Swift Interoperability in Depth
140/173
Tuples
Generics Enums and structs
objc attribute verifies that the declaration can be used in Objective-C
func myGenericMethod(x: T) -> (String, String) { }@objc// error: not expressible in Objective-C
Controlling Objective-C Names
objc attribute can be used to change the name of an Objective-C method bl d B l {
-
8/10/2019 407 Swift Interoperability in Depth
141/173
var enabled: Bool {
set { }}
get { }
Controlling Objective-C Names
objc attribute can be used to change the name of an Objective-C method bl d B l { // t i d bl d
-
8/10/2019 407 Swift Interoperability in Depth
142/173
var enabled: Bool {
set { }}
// property is named enabled // getter is named // setter is named setEnabled:
get { } enabled
Controlling Objective-C Names
objc attribute can be used to change the name of an Objective-C method var enabled: Bool { // property is named enabled
-
8/10/2019 407 Swift Interoperability in Depth
143/173
var enabled: Bool {
set { }}
// property is named enabled // getter is named // setter is named setEnabled:
@objc(isEnabled) get { } isEnabled
Controlling Objective-C Names
objc attribute can be used to change the name of an Objective-C method var enabled: Bool { // property is named enabled
-
8/10/2019 407 Swift Interoperability in Depth
144/173
var enabled: Bool {
set { }}
Or the name of a class
@objc(ABCMyDocument) class MyDocument : UIDocument { // }
// property is named enabled // getter is named // setter is named setEnabled:
@objc(isEnabled) get { } isEnabled
-
8/10/2019 407 Swift Interoperability in Depth
145/173
CF Interoperability
CF in Objective-C
void drawGradientRect(CGContextRef context, CGColorRef startColor, CGColorRef endColor, CGFloat width, CGFloat height) {
-
8/10/2019 407 Swift Interoperability in Depth
146/173
}
CF in Objective-C
void drawGradientRect(CGContextRef context, CGColorRef startColor, CGColorRef endColor, CGFloat width, CGFloat height) {
-
8/10/2019 407 Swift Interoperability in Depth
147/173
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();NSArray *colors = @[(__bridge id)startColor, (__bridge id)endColor];CGFloat locations[2] = {0.0, 1.0};CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(CFArrayRef)colors, locations);
}
void drawGradientRect(CGContextRef context, CGColorRef startColor, CGColorRef endColor, CGFloat width, CGFloat height) {
CF in Objective-CBridge casts
-
8/10/2019 407 Swift Interoperability in Depth
148/173
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();NSArray *colors = @[ (__bridge id) startColor, (__bridge id) endColor];CGFloat locations[2] = {0.0, 1.0};CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(CFArrayRef) colors, locations);
}
void drawGradientRect(CGContextRef context, CGColorRef startColor, CGColorRef endColor, CGFloat width, CGFloat height) {
CF in Objective-C Three kinds of arrays
-
8/10/2019 407 Swift Interoperability in Depth
149/173
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();NSArray *colors = @[(__bridge id)startColor, (__bridge id)endColor];CGFloat locations[2] = {0.0, 1.0};CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
( CFArrayRef )colors, locations);
}
CF in Objective-C
void drawGradientRect(CGContextRef context, CGColorRef startColor, CGColorRef endColor, CGFloat width, CGFloat height) {
-
8/10/2019 407 Swift Interoperability in Depth
150/173
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();NSArray *colors = @[(__bridge id)startColor, (__bridge id)endColor];CGFloat locations[2] = {0.0, 1.0};CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(CFArrayRef)colors, locations);
CGPoint startPoint = CGPointMake (width / 2, 0);CGPoint endPoint = CGPointMake (width / 2, height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
}
-
8/10/2019 407 Swift Interoperability in Depth
151/173
CF in Swift
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
-
8/10/2019 407 Swift Interoperability in Depth
152/173
}
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
Managed CF Objects
-
8/10/2019 407 Swift Interoperability in Depth
153/173
let colorSpace = CGColorSpaceCreateDeviceRGB()
}
-
8/10/2019 407 Swift Interoperability in Depth
154/173
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
Managed CF Objects
-
8/10/2019 407 Swift Interoperability in Depth
155/173
let colorSpace = CGColorSpaceCreateDeviceRGB()
}// colorSpace automatically released
// inferred as CGColorSpace
Toll-Free Bridging Conversions
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
-
8/10/2019 407 Swift Interoperability in Depth
156/173
let colorSpace = CGColorSpaceCreateDeviceRGB() let gradient = CGGradientCreateWithColors(colorSpace,[startColor, endColor] ,[0.0, 1.0])
}
C Interoperability
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
-
8/10/2019 407 Swift Interoperability in Depth
157/173
let colorSpace = CGColorSpaceCreateDeviceRGB() let gradient = CGGradientCreateWithColors(colorSpace,[startColor, endColor],[0.0, 1.0] )
}
Construction of C Structs
func drawGradientRect(context: CGContext, startColor: CGColor, endColor: CGColor, width: CGFloat, height: CGFloat) {
-
8/10/2019 407 Swift Interoperability in Depth
158/173
let colorSpace = CGColorSpaceCreateDeviceRGB() let gradient = CGGradientCreateWithColors(colorSpace,[startColor, endColor],[0.0, 1.0])
let startPoint = CGPoint ( x: width / 2, y: 0)let endPoint = CGPoint ( x: width / 2, y: height)CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
}
Explicitly Bridged APIs
Some CF APIs have not been audited for implicit bridgingCGColorRef CGColorGetRandomColor(void);
-
8/10/2019 407 Swift Interoperability in Depth
159/173
Explicitly Bridged APIs
Some CF APIs have not been audited for implicit bridgingCGColorRef CGColorGetRandomColor(void);
-
8/10/2019 407 Swift Interoperability in Depth
160/173
Swift uses Unmanaged when the ownership convention is unknown func CGColorGetRandomColor() -> Unmanaged
Working with Unmanaged Objects
Unmanaged enables manual memory managementstruct Unmanaged {
f t k U t i dV l () > T // f +0 t
-
8/10/2019 407 Swift Interoperability in Depth
161/173
func takeUnretainedValue() -> T // for +0 returns func takeRetainedValue() -> T // for +1 returns
}
Working with Unmanaged Objects
Unmanaged enables manual memory managementstruct Unmanaged {
f t k U t i dV l () > T // for +0 ret rns
-
8/10/2019 407 Swift Interoperability in Depth
162/173
func takeUnretainedValue() -> T // for +0 returns func takeRetainedValue() -> T // for +1 returns
}
Working with Unmanaged Objects
Unmanaged enables manual memory managementstruct Unmanaged {
func takeUnretainedValue() > T // for +0 returns
-
8/10/2019 407 Swift Interoperability in Depth
163/173
func takeUnretainedValue() -> T // for +0 returns func takeRetainedValue() -> T // for +1 returns
}
Use it to work with unaudited CF APIs let color = CGColorGetRandomColor(). takeUnretainedValue ()
Working with Unmanaged Objects
Unmanaged enables manual memory managementstruct Unmanaged {
func takeUnretainedValue() > T // for +0 returns
-
8/10/2019 407 Swift Interoperability in Depth
164/173
func takeUnretainedValue() -> T // for +0 returns func takeRetainedValue() -> T // for +1 returns
}
Use it to work with unaudited CF APIs let color = CGColorGetRandomColor(). takeUnretainedValue ()
// inferred as CGColor
Working with Unmanaged Objects
Unmanaged enables manual memory managementstruct Unmanaged {
func takeUnretainedValue() > T // for +0 returns
-
8/10/2019 407 Swift Interoperability in Depth
165/173
func takeUnretainedValue() -> T // for +0 returns func takeRetainedValue() -> T // for +1 returns
}
Use it to work with unaudited CF APIs let color = CGColorGetRandomColor(). takeUnretainedValue ()
func retain() -> Unmanagedfunc release()func autorelease() -> Unmanaged
// inferred as CGColor
Implicit Bridging
Audit CF APIs to ensure that conform to CF memory conventions
CGColorRef CGColorGetRandomColor(void);
-
8/10/2019 407 Swift Interoperability in Depth
166/173
CGColorRef CGColorGetRandomColor(void);
Swift uses Unmanaged when the ownership convention is unknown func CGColorGetRandomColor() -> Unmanaged
Implicit Bridging
Audit CF APIs to ensure that conform to CF memory conventions CF_IMPLICIT_BRIDGING_ENABLED
CGColorRef CGColorGetRandomColor(void);
-
8/10/2019 407 Swift Interoperability in Depth
167/173
CGColorRef CGColorGetRandomColor(void);CF_IMPLICIT_BRIDGING_DISABLED
Swift uses Unmanaged when the ownership convention is unknown func CGColorGetRandomColor() -> Unmanaged
Implicit Bridging
Audit CF APIs to ensure that conform to CF memory conventions CF_IMPLICIT_BRIDGING_ENABLED
CGColorRef CGColorGetRandomColor(void);
-
8/10/2019 407 Swift Interoperability in Depth
168/173
CGColorRef CGColorGetRandomColor(void);CF_IMPLICIT_BRIDGING_DISABLED
Implicit bridging eliminates Unmanagedfunc CGColorGetRandomColor() -> CGColor
Summary
Seamless interoperability between Swift and Objective-C Let the tools help you understand the relationship
-
8/10/2019 407 Swift Interoperability in Depth
169/173
Bridging of Core Cocoa types Prefer native strings, arrays, dictionaries
Automated CF memory management
More Information
Dave DeLongDeveloper Tools Evangelist
delong@apple com
-
8/10/2019 407 Swift Interoperability in Depth
170/173
DocumentationUsing Swift with Cocoa and Objective-Chttp://apple.com
Apple Developer Forums
http://devforums.apple.com
Related Sessions
http://devforums.apple.com/http://devforums.apple.com/ -
8/10/2019 407 Swift Interoperability in Depth
171/173
Labs
-
8/10/2019 407 Swift Interoperability in Depth
172/173
-
8/10/2019 407 Swift Interoperability in Depth
173/173