SlideShare a Scribd company logo
1 of 35
Download to read offline
A glimpse into Protocols with
Associated Type and type Erasure
Denis Poifol
Cocoaheads Lyon, le 17 Mai 2018
2//
Sommaire
01 //
02 //
03 //
Protocols with Associated Type (PAT)
Type wrapping
Type Erasure
3//
01 //
Protocols with Associated Type (PAT)
4//
protocol Identifiable {
associatedtype Identifier
var id: Identifier { get }
}
struct IntIdentifiableStruct: Identifiable {
typealias Identifier = Int
let id: Int
/* Other properties */
}
struct StringIdentifiableStruct: Identifiable {
let id: String
/* Other properties */
}
Declaration and implementation
5//
extension Equatable where Self: Identifiable, Self.Identifier: Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
}
Extension
6//
extension Equatable where Self: Identifiable, Self.Identifier: Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
}
extension Hashable where Self: Identifiable, Self.Identifier: Hashable {
var hashValue: Int { return id.hashValue }
}
Extension
7//
extension Equatable where Self: Identifiable, Self.Identifier: Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
}
extension Hashable where Self: Identifiable, Self.Identifier: Hashable {
var hashValue: Int { return id.hashValue }
}
extension StringIdentifiableStruct: Hashable {}
Extension
8//
let identifiable: Identifiable Protocol 'Identifiable' can only be used
as a generic constraint because it has Self or associated type requirements
Existential
9//
Protocol with Associated Types
● Default protocol functionalities
● Placeholder for one or multiple types
● No existential type
● A given type can conform to a PAT only in
one way
Note: Protocol with associated type are not generic protocols (which do not
exist in swift)
10//
02 //
Type Wrapping
11//
Configurable protocol
protocol Configurable {
associatedtype Model
func configure(with model: Model)
}
12//
Configurable protocol
protocol Configurable {
associatedtype Model
func configure(with model: Model)
}
extension UILabel: Configurable {
func configure(with model: String) {
text = model
}
}
13//
Configurable protocol
protocol Configurable {
associatedtype Model
func configure(with model: Model)
}
extension UILabel: Configurable {
func configure(with model: String) {
text = model
}
}
extension UIButton: ConfigurableView {
func configure(with model: String) {
setTitle(model, for: .normal)
}
}
14//
Wrap the implementing class inside of a generic type
struct ConfigurableWrapper<ConcreteClass: Configurable>: Configurable {
typealias Model = ConcreteClass.Model
private let wrappedInstance: ConcreteClass
init(_ wrappedInstance: ConcreteClass) {
self.wrappedInstance = wrappedInstance
}
func configure(with model: Model) {
wrappedInstance.configure(with: model)
}
}
15//
Wrap the implementing class inside of a generic type
let label = UILabel()
let configurable = ConfigurableWrapper(label)
type(of: configurable)// ConfigurableWrapper<UILabel>
16//
03 //
Type Erasure
17//
Type Erasure
What do we want to achieve ?
Store object conforming to a PAT regardless of
their actual type but defined by their associated
type(s)
18//
What do we want to achieve
protocol ViewContract {
var successView: AnyConfigurable<String> { get }
var goalView: AnyConfigurable<String> { get }
var successImageView: AnyConfigurable<UIImage> { get }
}
19//
What do we want to achieve
protocol ViewContract {
var successView: AnyConfigurable<String> { get }
var goalView: AnyConfigurable<String> { get }
var successImageView: AnyConfigurable<UIImage> { get }
}
var stringConfigurables: [AnyConfigurable<String>] = [
successUIElement,
goalUIElement,
]
let models = [
"Success",
"Present view to data layer wrapped as AnyConfigurable",
]
zip(stringConfigurable, models)
.forEach { $0.0.configure(with: $0.1) }
20//
Configurable
Type Erasure Pattern in Standard Library
Protocol
Associated
Type
Concrete
Type
21//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
Type Erasure Pattern in Standard Library
Protocol
Associated
Type
Concrete
Type
22//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
23//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
class _AnyConfigurableBase<ModelObject>: Configurable
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
24//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
class _AnyConfigurableBase<ModelObject>: Configurable
class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model>
init(_ configurable: ActualType)
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
25//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
class _AnyConfigurableBase<ModelObject>: Configurable
class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model>
init(_ configurable: ActualType)
final class AnyConfigurable<Model>: Configurable
init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
26//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
class _AnyConfigurableBase<ModelObject>: Configurable
class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model>
init(_ configurable: ActualType)
final class AnyConfigurable<Model>: Configurable
init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
27//
Configurable
String
UIImage
UILabel
UIImageView
UIButton
class _AnyConfigurableBase<ModelObject>: Configurable
class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model>
init(_ configurable: ActualType)
final class AnyConfigurable<Model>: Configurable
init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model
Type Erasure Pattern in Standard Library
Abstract Base
Private Box
Public Wrapper
Protocol
Associated
Type
Concrete
Type
28//
Implementing the abstract base class
class _AnyConfigurableBase<ModelObject>: Configurable {
typealias Model = ModelObject
}
29//
Implementing the abstract base class
class _AnyConfigurableBase<ModelObject>: Configurable {
typealias Model = ModelObject
init() {
guard type(of: self) != _AnyConfigurableBase.self else {
fatalError("This class cannot be implemented")
}
}
func configure(with model: ModelObject) {
fatalError("Must be overiden")
}
}
30//
Create an amphibological box class
class _AnyConfigurableBox<ActualType: Configurable>:
_AnyConfigurableBase<ActualType.Model> {
private let configurable: ActualType
init(_ configurable: ActualType) {
self.configurable = configurable
}
override func configure(with model: Model) {
configurable.configure(with: model)
}
}
31//
Implementing the final wrapper
final class AnyConfigurable<Model>: Configurable {
private let box: _AnyConfigurableBase<Model>
init<Concrete: Configurable>(_ concrete: Concrete)
where Concrete.Model == Model {
box = _AnyConfigurableBox(concrete)
}
func configure(with model: Model) {
box.configure(with: model)
}
}
32//
What do we want to achieve
protocol ViewContract {
var successView: AnyConfigurable<String> { get }
var goalView: AnyConfigurable<String> { get }
var successImageView: AnyConfigurable<UIImage> { get }
}
var stringConfigurables: [AnyConfigurable<String>] = [
successUIElement,
goalUIElement,
]
let models = [
"Success",
"Present view to data layer wrapped as AnyConfigurable",
]
zip(stringConfigurable, models)
.forEach { $0.0.configure(with: $0.1) }
33//
Implementing ViewContract
class ViewController: UIViewController, ViewContract {
private(set) lazy var successView = AnyConfigurable(label)
private(set) lazy var goalView = AnyConfigurable(button)
private(set) lazy var successImageView = AnyConfigurable(imageView)
private var label = UILabel()
private var button = UIButton()
private var imageView = UIImageView()
// ViewController implementation
}
34//
Read More
Great article from bigNerdRanch that inspired this talk
https://www.bignerdranch.com/blog/breaking-down-type-erasures-in-swift/
Swift Generic Manifesto
https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md
My github with a playground related to this talk
https://github.com/denisPoifol/Talks/
Merci.
35//
Denis Poifol
Junior Software Engineer
+33 6 58 90 85 54
denis.poifol@fabernovel.com

More Related Content

What's hot

What's hot (10)

core java
core javacore java
core java
 
Js: master prototypes
Js: master prototypesJs: master prototypes
Js: master prototypes
 
Lesson6
Lesson6Lesson6
Lesson6
 
Lesson 4
Lesson 4Lesson 4
Lesson 4
 
Java2
Java2Java2
Java2
 
Pythia Reloaded: An Intelligent Unit Testing-Based Code Grader for Education
Pythia Reloaded: An Intelligent Unit Testing-Based Code Grader for EducationPythia Reloaded: An Intelligent Unit Testing-Based Code Grader for Education
Pythia Reloaded: An Intelligent Unit Testing-Based Code Grader for Education
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
 
Week 06 Modular Javascript_Brandon, S. H. Wu
Week 06 Modular Javascript_Brandon, S. H. WuWeek 06 Modular Javascript_Brandon, S. H. Wu
Week 06 Modular Javascript_Brandon, S. H. Wu
 
Javascript Prototype Visualized
Javascript Prototype VisualizedJavascript Prototype Visualized
Javascript Prototype Visualized
 
Action Script
Action ScriptAction Script
Action Script
 

Similar to A glimpse into protocols with associated type and type erasure

Parsley & Flex
Parsley & FlexParsley & Flex
Parsley & Flex
prideconan
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
rashmita_mishra
 

Similar to A glimpse into protocols with associated type and type erasure (20)

Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Ej Chpt#4 Final
Ej Chpt#4 FinalEj Chpt#4 Final
Ej Chpt#4 Final
 
Abstract factory
Abstract factoryAbstract factory
Abstract factory
 
Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Devoxx 2012 (v2)
Devoxx 2012 (v2)Devoxx 2012 (v2)
Devoxx 2012 (v2)
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Parsley & Flex
Parsley & FlexParsley & Flex
Parsley & Flex
 
C questions
C questionsC questions
C questions
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
OOC MODULE1.pptx
OOC MODULE1.pptxOOC MODULE1.pptx
OOC MODULE1.pptx
 
Creational pattern 2
Creational pattern 2Creational pattern 2
Creational pattern 2
 
Creating and destroying objects
Creating and destroying objectsCreating and destroying objects
Creating and destroying objects
 
Structural pattern 3
Structural pattern 3Structural pattern 3
Structural pattern 3
 
Java Programming - 04 object oriented in java
Java Programming - 04 object oriented in javaJava Programming - 04 object oriented in java
Java Programming - 04 object oriented in java
 
Design patterns in Java - Monitis 2017
Design patterns in Java - Monitis 2017Design patterns in Java - Monitis 2017
Design patterns in Java - Monitis 2017
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
 

Recently uploaded

Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
FIDO Alliance
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
FIDO Alliance
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
FIDO Alliance
 

Recently uploaded (20)

الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development Companies
 
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
How to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in PakistanHow to Check GPS Location with a Live Tracker in Pakistan
How to Check GPS Location with a Live Tracker in Pakistan
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 

A glimpse into protocols with associated type and type erasure

  • 1. A glimpse into Protocols with Associated Type and type Erasure Denis Poifol Cocoaheads Lyon, le 17 Mai 2018
  • 2. 2// Sommaire 01 // 02 // 03 // Protocols with Associated Type (PAT) Type wrapping Type Erasure
  • 3. 3// 01 // Protocols with Associated Type (PAT)
  • 4. 4// protocol Identifiable { associatedtype Identifier var id: Identifier { get } } struct IntIdentifiableStruct: Identifiable { typealias Identifier = Int let id: Int /* Other properties */ } struct StringIdentifiableStruct: Identifiable { let id: String /* Other properties */ } Declaration and implementation
  • 5. 5// extension Equatable where Self: Identifiable, Self.Identifier: Equatable { static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.id == rhs.id } } Extension
  • 6. 6// extension Equatable where Self: Identifiable, Self.Identifier: Equatable { static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.id == rhs.id } } extension Hashable where Self: Identifiable, Self.Identifier: Hashable { var hashValue: Int { return id.hashValue } } Extension
  • 7. 7// extension Equatable where Self: Identifiable, Self.Identifier: Equatable { static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.id == rhs.id } } extension Hashable where Self: Identifiable, Self.Identifier: Hashable { var hashValue: Int { return id.hashValue } } extension StringIdentifiableStruct: Hashable {} Extension
  • 8. 8// let identifiable: Identifiable Protocol 'Identifiable' can only be used as a generic constraint because it has Self or associated type requirements Existential
  • 9. 9// Protocol with Associated Types ● Default protocol functionalities ● Placeholder for one or multiple types ● No existential type ● A given type can conform to a PAT only in one way Note: Protocol with associated type are not generic protocols (which do not exist in swift)
  • 11. 11// Configurable protocol protocol Configurable { associatedtype Model func configure(with model: Model) }
  • 12. 12// Configurable protocol protocol Configurable { associatedtype Model func configure(with model: Model) } extension UILabel: Configurable { func configure(with model: String) { text = model } }
  • 13. 13// Configurable protocol protocol Configurable { associatedtype Model func configure(with model: Model) } extension UILabel: Configurable { func configure(with model: String) { text = model } } extension UIButton: ConfigurableView { func configure(with model: String) { setTitle(model, for: .normal) } }
  • 14. 14// Wrap the implementing class inside of a generic type struct ConfigurableWrapper<ConcreteClass: Configurable>: Configurable { typealias Model = ConcreteClass.Model private let wrappedInstance: ConcreteClass init(_ wrappedInstance: ConcreteClass) { self.wrappedInstance = wrappedInstance } func configure(with model: Model) { wrappedInstance.configure(with: model) } }
  • 15. 15// Wrap the implementing class inside of a generic type let label = UILabel() let configurable = ConfigurableWrapper(label) type(of: configurable)// ConfigurableWrapper<UILabel>
  • 17. 17// Type Erasure What do we want to achieve ? Store object conforming to a PAT regardless of their actual type but defined by their associated type(s)
  • 18. 18// What do we want to achieve protocol ViewContract { var successView: AnyConfigurable<String> { get } var goalView: AnyConfigurable<String> { get } var successImageView: AnyConfigurable<UIImage> { get } }
  • 19. 19// What do we want to achieve protocol ViewContract { var successView: AnyConfigurable<String> { get } var goalView: AnyConfigurable<String> { get } var successImageView: AnyConfigurable<UIImage> { get } } var stringConfigurables: [AnyConfigurable<String>] = [ successUIElement, goalUIElement, ] let models = [ "Success", "Present view to data layer wrapped as AnyConfigurable", ] zip(stringConfigurable, models) .forEach { $0.0.configure(with: $0.1) }
  • 20. 20// Configurable Type Erasure Pattern in Standard Library Protocol Associated Type Concrete Type
  • 21. 21// Configurable String UIImage UILabel UIImageView UIButton Type Erasure Pattern in Standard Library Protocol Associated Type Concrete Type
  • 22. 22// Configurable String UIImage UILabel UIImageView UIButton Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 23. 23// Configurable String UIImage UILabel UIImageView UIButton class _AnyConfigurableBase<ModelObject>: Configurable Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 24. 24// Configurable String UIImage UILabel UIImageView UIButton class _AnyConfigurableBase<ModelObject>: Configurable class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model> init(_ configurable: ActualType) Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 25. 25// Configurable String UIImage UILabel UIImageView UIButton class _AnyConfigurableBase<ModelObject>: Configurable class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model> init(_ configurable: ActualType) final class AnyConfigurable<Model>: Configurable init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 26. 26// Configurable String UIImage UILabel UIImageView UIButton class _AnyConfigurableBase<ModelObject>: Configurable class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model> init(_ configurable: ActualType) final class AnyConfigurable<Model>: Configurable init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 27. 27// Configurable String UIImage UILabel UIImageView UIButton class _AnyConfigurableBase<ModelObject>: Configurable class _AnyConfigurableBox<ActualType: Configurable>:_AnyConfigurableBase<ActualType.Model> init(_ configurable: ActualType) final class AnyConfigurable<Model>: Configurable init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model Type Erasure Pattern in Standard Library Abstract Base Private Box Public Wrapper Protocol Associated Type Concrete Type
  • 28. 28// Implementing the abstract base class class _AnyConfigurableBase<ModelObject>: Configurable { typealias Model = ModelObject }
  • 29. 29// Implementing the abstract base class class _AnyConfigurableBase<ModelObject>: Configurable { typealias Model = ModelObject init() { guard type(of: self) != _AnyConfigurableBase.self else { fatalError("This class cannot be implemented") } } func configure(with model: ModelObject) { fatalError("Must be overiden") } }
  • 30. 30// Create an amphibological box class class _AnyConfigurableBox<ActualType: Configurable>: _AnyConfigurableBase<ActualType.Model> { private let configurable: ActualType init(_ configurable: ActualType) { self.configurable = configurable } override func configure(with model: Model) { configurable.configure(with: model) } }
  • 31. 31// Implementing the final wrapper final class AnyConfigurable<Model>: Configurable { private let box: _AnyConfigurableBase<Model> init<Concrete: Configurable>(_ concrete: Concrete) where Concrete.Model == Model { box = _AnyConfigurableBox(concrete) } func configure(with model: Model) { box.configure(with: model) } }
  • 32. 32// What do we want to achieve protocol ViewContract { var successView: AnyConfigurable<String> { get } var goalView: AnyConfigurable<String> { get } var successImageView: AnyConfigurable<UIImage> { get } } var stringConfigurables: [AnyConfigurable<String>] = [ successUIElement, goalUIElement, ] let models = [ "Success", "Present view to data layer wrapped as AnyConfigurable", ] zip(stringConfigurable, models) .forEach { $0.0.configure(with: $0.1) }
  • 33. 33// Implementing ViewContract class ViewController: UIViewController, ViewContract { private(set) lazy var successView = AnyConfigurable(label) private(set) lazy var goalView = AnyConfigurable(button) private(set) lazy var successImageView = AnyConfigurable(imageView) private var label = UILabel() private var button = UIButton() private var imageView = UIImageView() // ViewController implementation }
  • 34. 34// Read More Great article from bigNerdRanch that inspired this talk https://www.bignerdranch.com/blog/breaking-down-type-erasures-in-swift/ Swift Generic Manifesto https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md My github with a playground related to this talk https://github.com/denisPoifol/Talks/
  • 35. Merci. 35// Denis Poifol Junior Software Engineer +33 6 58 90 85 54 denis.poifol@fabernovel.com