protocols promised-land-2
TRANSCRIPT
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/