Protocols and the
Promised Land
@MicheleTitolo
Swift is shiny! And new!
Swift is not Objective-C
Interop
as? as? as?
as? lies
🚫
let vendor = ObjcObject()
let items = vendor.giveMeItems() as? [Fruit]
let vendor = ObjcObject()
let items = vendor.giveMeItems().map { $0 as Fruit }
@objc spreads like a virus
🚫
@objc protocol SomeProtocol {
func someFunc()
}
class MyClass: SomeProtocol {}
@objc protocol SomeProtocol {
func someFunc()
}
@objc class MyClass: NSObject, SomeProtocol {}
Swift > Objc > Swift
Can’t #import “MyApp-Swift.h” in
header
Can’t conform, can’t subclass
Bridging
many parts of Swift don’t bridge
Does this really need to be used in
Objective-C?
framework headers can’t be in
bridging header
use @import
Partial bridging
-Swift.h will leave out funcs/vars that
don’t bridge
Again: does this really need to be
bridged?
Type System
properties can have 1 type
protocol Themeable {}
class ListViewController: UIViewController, Themeable {}
var themedViewController: // UIViewController, Themeable ????
two workarounds
public protocol ViewControllerProtocol {
var view: UIView! { get }
var storyboard: UIStoryboard? { get }
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil:
NSBundle?)
func viewDidLoad()
// etc
}
protocol ThemeableViewController: Themeable, ViewControllerProtocol {}
var themedViewController: ThemeableViewController
Swift-y but hack-y
var themed: Themeable {
get {
return self.viewController as! Themeable
}
set(newThemeable) {
if let themedViewController = newThemeable as? UIViewController{
viewController = themedViewController
}
}
}
var viewController: UIViewController
init<T where T: Themeable, T: UIViewController>(viewController: T) {
self.viewController = viewController
}
Also swfit-y also hack-y
Can’t override type with
inheritance
🚫Deep object hierarchies
Protocols
Composition instead
of inheritance
Protocols and inheritance
don’t mix
use POP to mock
Generics
Can’t reference a generic protocol
protocol Holder {
typealias Item
var items: [Item] { get }
}
class Basket<Thing>: Holder{
var items: [Thing] = []
func add(item: Thing) {
items.append(item)
}
}
🚫
🚫
var someHolder: Holder
var someBasket: Basket
🚫 var someHolder: Holder<Peach>
var someBasket: Basket<Peach>
Covariance only works with generic
classes
Covariance: If a Cat is an Animal
func feed(animal: Animal)
can receive a Cat
🚫
🚫
typealias Object
typealias Object: String
typealias RoundObject: Object
generic classes can specify type
requirements
class Basket<Thing: Fruit> {
var items: [Thing] = []
func add(item: Thing) {
items.append(item)
}
}
🚫
class Basket<Thing: Fruit> {
var items: [Thing] = []
func add(item: Thing) {
items.append(item)
}
}
class FruitBasket: Basket<Fruit> {}
class PeachBasket: FruitBasket<Peach> {}
🚫
class Bag<Stuff> {
class Basket<Thing: Stuff> {
var items: [Thing] = []
func add(item: Thing) {
items.append(item)
}
}
}
Generic non-NSObjects have
issues
Explicitly call out class for now
Swift introduces
awesome new patterns
Thanks!
@MicheleTitolo
Photo Credits
• https://www.flickr.com/photos/83073191@N00/21709516808/
• https://www.flickr.com/photos/64181484@N04/21946459678/
• https://www.flickr.com/photos/66904032@N05/18905223864/
• https://www.flickr.com/photos/27454212@N00/22120629112/
• https://www.flickr.com/photos/8725928@N02/24439195435/
• https://www.flickr.com/photos/28480761@N04/24143685631/

Protocols promised-land-2