SlideShare a Scribd company logo
Donny Wals
@donnywals

https://donnywals.com

🎸 🎓 #
! !
#adventofswift
One article a day in December until Christmas eve
Building reusable components
with generics and protocols
Goals
Goals
• Learn how to design code that uses Generics
Goals
• Learn how to design code that uses Generics
• Understand simple generics and associated types
Goals
• Learn how to design code that uses Generics
• Understand simple generics and associated types
• Know how to use protocols with associated types with generics
Goals
• Learn how to design code that uses Generics
• Understand simple generics and associated types
• Know how to use protocols with associated types with generics
• To (not) blow your mind (too much)
“I want to have a cache. But it should be able to cache, like,
anything.”
“I want to have a cache. But it should be able to cache, like,
anything.”
“And it should have a remote backup, so if the item isn’t available
locally, I can take it from the server.”
“I want to have a cache. But it should be able to cache, like,
anything.”
“And it should have a remote backup, so if the item isn’t available
locally, I can take it from the server.”
“And when the data is taken from the server, the local cache should
be updated with the remote version.”
“I want to have a cache. But it should be able to cache, like,
anything.”
“And it should have a remote backup, so if the item isn’t available
locally, I can take it from the server.”
“And when the data is taken from the server, the local cache should
be updated with the remote version.”
“And I don’t want to create special cache managers for every type of
object or something. Maybe the underlying storage could be specific,
but that’s it!”
–Me, in the morning. Before I realize what I’m about to get myself into.
“I want to have a cache. But it should be able to cache, like,
anything.”
“And it should have a remote backup, so if the item isn’t available
locally, I can take it from the server.”
“And when the data is taken from the server, the local cache should
be updated with the remote version.”
“And I don’t want to create special cache managers for every type of
object or something. Maybe the underlying storage could be specific,
but that’s it!”
$ the appropriate response
$ the appropriate response
$ my initial response
$ my initial response
Designing the call site
Designing the call site
• Figure out how I want to use whatever it is that I’m building
Designing the call site
• Figure out how I want to use whatever it is that I’m building
• This helps to validate your ideas
Designing the call site
• Figure out how I want to use whatever it is that I’m building
• This helps to validate your ideas
• Don’t worry about any generics, type names or details yet
Designing the call site
An easy to use, straightforward API that uses existing data stores
and applies the caching logic internally.
Designing the implementation
Designing the implementation
And a fairly simple fetch method that tries to find an item in a local
store, and uses the remote as a back-up.
So far, so good
So far, so good
But this isn’t the actual thing, is it?
So far, so good
But this isn’t the actual thing, is it?
Oh good, because we were promised
generics and protocols and the possibility
of getting our minds blown.
Step 1 - Generics🎓
Step 1 - Generics🎓
Step 1 - Generics
Generic
🎓
Step 1 - Generics🎓
Step 1 - Generics
Generic Placeholder
🎓
Step 1 - Generics
Generic Placeholder
<YourGeneric>
🎓
Step 1 - Generics🎓
Step 1 - Generics
The Generic defined on the type and the Generic type of the function
argument must always be the same type
🎓
Step 1 - Generics🎓
Step 1 - Generics🎓
Step 1 - Generics🎓
Step 1 - Generics🎓
Step 1 - Generics
The compiler will check and enforce that you don’t have a type
mismatch
🎓
A (kind of) real example%
A (kind of) real example%
These view models are very similar
A (kind of) real example%
Much nicer
A (kind of) real example%
And easy to use!
Step 1 - Generics&
Step 1 - Generics
Our cache backed data store will be generic over T and use a Result
of T?, or Optional<T>
&
Step 1 - Generics
Our cache backed data store will be generic over T and use a Result
of T?, or Optional<T>
&
Step 2 - Protocols🎓
Step 2 - Protocols🎓
Step 2 - Protocols🎓
Step 2 - Protocols
Protocols don’t have generics like types do. We can’t add T to the
declaration and we also can’t use T as a type for methods.
🎓
Step 2 - Protocols🎓
Step 2 - Protocols🎓
Associated types can be used to define placeholder types.
Step 2 - Protocols🎓
We can use these associated types as if they are real types.
Objects that conform to this protocol define the associated type.
Step 2 - Protocols🎓
Step 2 - Protocols🎓
The Swift compiler can infer the “real” type of the associated type
when we use it in the conforming type.
Step 2 - Protocols🎓
Note that the same type must be used in all places where the
associated type was used in the protocol
We need to rewind🛑
We need to rewind🛑
Currently anything can be our associated type
We need to rewind🛑
Currently anything can be our associated type
We need to rewind🛑
and that’s a problem
We need to rewind🛑
and that’s a problem
Why would that be a problem? Wasn’t our
goal to cache anything?
Step 2 - Protocols🎓
Step 2 - Protocols🎓
You can constrain associated types to certain protocols.
The compiler will enforce this constraint.
Step 2 - Protocols&
Step 2 - Protocols&
Step 2 - Protocols&
Step 2 - Protocols&
Step 2 - Protocols&
Step 3 - Assemble!🎓
Step 3 - Assemble!🎓
Step 3 - Assemble!🎓
Very nice.
Step 3 - Assemble!🎓
Okay, maybe not so nice…
Step 3 - Assemble!🎓
Step 3 - Assemble!🎓
We can give names to generics
Step 3 - Assemble!🎓
And we can constrain them to protocols
Step 3 - Assemble!🎓
And we can now use the LocalStore’s associated type as the
success type for our Result.
Step 3 - Assemble!&
Step 3 - Assemble!&
We can now use the local store’s find method to get a
Result<Local.StoredObject, Error>
Step 3 - Assemble!&
If the object was found, the completion closure is called with the
Local.StoredObject item that we’ve found.
Step 3 - Assemble!&
Remote store is used as backup…
Step 3 - Assemble!&
Think about this line for just a second.
Flashback🤔
Flashback🤔
LocalStore has a StoredObject
Flashback🤔
RemoteStore has a TargetObject
Flashback🤔
RemoteStore.TargetObject can’t be used as LocalStore.StoredObject
Step 3 - Assemble!🎓
This is a problem…
Step 3 - Assemble!&
Step 3 - Assemble!&
Step 3 - Assemble!&
The compiler can now proof and enforce that
Local.StoredObject and Remote.TargetObject are the same
Step 3 - Assemble!&
Step 3 - Assemble!&
This is now okay
Step 3 - Assemble!&
And so is this
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
• Conforms to LocalStore
• LocalStore.StoredObject => User
Step 4 - Using the cache🚀
• Conforms to RemoteStore
• RemoteStore.TargetObject => User
• User is Decodable
Step 4 - Using the cache🚀
• Local == ArrayBackedUserStore
• Remote == RemoteUserStore
• Compiler can infer
Step 4 - Using the cache🚀
• We can proof that this is a User
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
Step 4 - Using the cache🚀
When is all this useful to know?
• Code duplication in Swift is often related to types. Generics can help you
clean this up.

• You’re most likely to encounter generics in your model/networking layer.

• If you want to write frameworks or SDKs.
In summary
In summary
• Figure out how you want to use your code first.
In summary
• Figure out how you want to use your code first.
• Then find out what that means for your implementation.
In summary
• Figure out how you want to use your code first.
• Then find out what that means for your implementation.
• If needed, introduce generics and protocols as abstractions.
In summary
• Figure out how you want to use your code first.
• Then find out what that means for your implementation.
• If needed, introduce generics and protocols as abstractions.
• Constrain your generics and associated types where needed so the
compiler can help you.
In summary
• Figure out how you want to use your code first.
• Then find out what that means for your implementation.
• If needed, introduce generics and protocols as abstractions.
• Constrain your generics and associated types where needed so the
compiler can help you.
• Generics can help you limit code duplication.
! !
#adventofswift
@donnywals
Thank you
Questions are always welcome
Ad

Recommended

A rough guide to JavaScript Performance
A rough guide to JavaScript Performance
allmarkedup
 
Ruby
Ruby
Aizat Faiz
 
Coldfusion
Coldfusion
Ram
 
WorkinOnTheRailsRoad
WorkinOnTheRailsRoad
webuploader
 
Workin ontherailsroad
Workin ontherailsroad
Jim Jones
 
Ruby Programming Language - Introduction
Ruby Programming Language - Introduction
Kwangshin Oh
 
Realtime Apps with Django
Realtime Apps with Django
Renyi Khor
 
Introduction to Ruby
Introduction to Ruby
kim.mens
 
Why Ruby
Why Ruby
Daniel Lv
 
Web development basics (Part-5)
Web development basics (Part-5)
Rajat Pratap Singh
 
Backend roadmap
Backend roadmap
wassimbenfatma1
 
NLP using JavaScript Natural Library
NLP using JavaScript Natural Library
Aniruddha Chakrabarti
 
Smalltalk and Business
Smalltalk and Business
Mariano Martínez Peck
 
Ruby on Rails Presentation
Ruby on Rails Presentation
Joost Hietbrink
 
Ruby On Rails Presentation
Ruby On Rails Presentation
ChanHan Hy
 
Writing Readable Code
Writing Readable Code
eddiehaber
 
Core data intermediate Workshop at NSSpain 2013
Core data intermediate Workshop at NSSpain 2013
Diego Freniche Brito
 
Drupalcon cph
Drupalcon cph
cyberswat
 
How we took our server side application to the cloud and liked what we got
How we took our server side application to the cloud and liked what we got
Baruch Sadogursky
 
The Good, the Bad and the Ugly things to do with android
The Good, the Bad and the Ugly things to do with android
Stanojko Markovik
 
Ajaxworld07
Ajaxworld07
tutorialsruby
 
Ajaxworld07
Ajaxworld07
tutorialsruby
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)
Tomas Doran
 
Tweakers Anonymous
Tweakers Anonymous
John Anderson
 
Javascript orientado a testes
Javascript orientado a testes
Alexandre Gomes
 
All of Javascript
All of Javascript
Togakangaroo
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
DroidConTLV
 
Write code that writes code!
Write code that writes code!
Jason Feinstein
 
Software Engineering Thailand: Programming with Scala
Software Engineering Thailand: Programming with Scala
Brian Topping
 
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Krzysztof (Chris) Ozog
 

More Related Content

What's hot (7)

Why Ruby
Why Ruby
Daniel Lv
 
Web development basics (Part-5)
Web development basics (Part-5)
Rajat Pratap Singh
 
Backend roadmap
Backend roadmap
wassimbenfatma1
 
NLP using JavaScript Natural Library
NLP using JavaScript Natural Library
Aniruddha Chakrabarti
 
Smalltalk and Business
Smalltalk and Business
Mariano Martínez Peck
 
Ruby on Rails Presentation
Ruby on Rails Presentation
Joost Hietbrink
 
Ruby On Rails Presentation
Ruby On Rails Presentation
ChanHan Hy
 

Similar to Building reusable components with generics and protocols (20)

Writing Readable Code
Writing Readable Code
eddiehaber
 
Core data intermediate Workshop at NSSpain 2013
Core data intermediate Workshop at NSSpain 2013
Diego Freniche Brito
 
Drupalcon cph
Drupalcon cph
cyberswat
 
How we took our server side application to the cloud and liked what we got
How we took our server side application to the cloud and liked what we got
Baruch Sadogursky
 
The Good, the Bad and the Ugly things to do with android
The Good, the Bad and the Ugly things to do with android
Stanojko Markovik
 
Ajaxworld07
Ajaxworld07
tutorialsruby
 
Ajaxworld07
Ajaxworld07
tutorialsruby
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)
Tomas Doran
 
Tweakers Anonymous
Tweakers Anonymous
John Anderson
 
Javascript orientado a testes
Javascript orientado a testes
Alexandre Gomes
 
All of Javascript
All of Javascript
Togakangaroo
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
DroidConTLV
 
Write code that writes code!
Write code that writes code!
Jason Feinstein
 
Software Engineering Thailand: Programming with Scala
Software Engineering Thailand: Programming with Scala
Brian Topping
 
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Krzysztof (Chris) Ozog
 
Automate Yo' Self
Automate Yo' Self
John Anderson
 
Dont run with scissors
Dont run with scissors
Morgan Roman
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
Mike Harris
 
Using React for the Mobile Web
Using React for the Mobile Web
C4Media
 
How to Reverse Engineer Web Applications
How to Reverse Engineer Web Applications
Jarrod Overson
 
Writing Readable Code
Writing Readable Code
eddiehaber
 
Core data intermediate Workshop at NSSpain 2013
Core data intermediate Workshop at NSSpain 2013
Diego Freniche Brito
 
Drupalcon cph
Drupalcon cph
cyberswat
 
How we took our server side application to the cloud and liked what we got
How we took our server side application to the cloud and liked what we got
Baruch Sadogursky
 
The Good, the Bad and the Ugly things to do with android
The Good, the Bad and the Ugly things to do with android
Stanojko Markovik
 
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development (2 - puppetconf 2013 edition)
Tomas Doran
 
Javascript orientado a testes
Javascript orientado a testes
Alexandre Gomes
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
DroidConTLV
 
Write code that writes code!
Write code that writes code!
Jason Feinstein
 
Software Engineering Thailand: Programming with Scala
Software Engineering Thailand: Programming with Scala
Brian Topping
 
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Code Camp NYC 2017 - How to deal with everything... | Chris Ozog - Codesushi
Krzysztof (Chris) Ozog
 
Dont run with scissors
Dont run with scissors
Morgan Roman
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
Mike Harris
 
Using React for the Mobile Web
Using React for the Mobile Web
C4Media
 
How to Reverse Engineer Web Applications
How to Reverse Engineer Web Applications
Jarrod Overson
 
Ad

More from Donny Wals (15)

Your 🧠 on Swift Concurrency
Your 🧠 on Swift Concurrency
Donny Wals
 
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Donny Wals
 
The combine triad
The combine triad
Donny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplace
Donny Wals
 
The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!
Donny Wals
 
Me and my importers
Me and my importers
Donny Wals
 
JSON and Swift, Still A Better Love Story Than Twilight
JSON and Swift, Still A Better Love Story Than Twilight
Donny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplace
Donny Wals
 
In Defense Of Core Data
In Defense Of Core Data
Donny Wals
 
Effectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple Platforms
Donny Wals
 
Improving apps with iOS 10 notifications (do iOS 2016)
Improving apps with iOS 10 notifications (do iOS 2016)
Donny Wals
 
Talk - git task managers and ci
Talk - git task managers and ci
Donny Wals
 
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Donny Wals
 
Marketing strategie Arto
Marketing strategie Arto
Donny Wals
 
Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012
Donny Wals
 
Your 🧠 on Swift Concurrency
Your 🧠 on Swift Concurrency
Donny Wals
 
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Donny Wals
 
The combine triad
The combine triad
Donny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplace
Donny Wals
 
The Testing Games: Mocking, yay!
The Testing Games: Mocking, yay!
Donny Wals
 
Me and my importers
Me and my importers
Donny Wals
 
JSON and Swift, Still A Better Love Story Than Twilight
JSON and Swift, Still A Better Love Story Than Twilight
Donny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplace
Donny Wals
 
In Defense Of Core Data
In Defense Of Core Data
Donny Wals
 
Effectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple Platforms
Donny Wals
 
Improving apps with iOS 10 notifications (do iOS 2016)
Improving apps with iOS 10 notifications (do iOS 2016)
Donny Wals
 
Talk - git task managers and ci
Talk - git task managers and ci
Donny Wals
 
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Donny Wals
 
Marketing strategie Arto
Marketing strategie Arto
Donny Wals
 
Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012
Donny Wals
 
Ad

Recently uploaded (20)

OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
“Key Requirements to Successfully Implement Generative AI in Edge Devices—Opt...
“Key Requirements to Successfully Implement Generative AI in Edge Devices—Opt...
Edge AI and Vision Alliance
 
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Securing Account Lifecycles in the Age of Deepfakes.pptx
Securing Account Lifecycles in the Age of Deepfakes.pptx
FIDO Alliance
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Improving Data Integrity: Synchronization between EAM and ArcGIS Utility Netw...
Improving Data Integrity: Synchronization between EAM and ArcGIS Utility Netw...
Safe Software
 
OpenPOWER Foundation & Open-Source Core Innovations
OpenPOWER Foundation & Open-Source Core Innovations
IBM
 
“Key Requirements to Successfully Implement Generative AI in Edge Devices—Opt...
“Key Requirements to Successfully Implement Generative AI in Edge Devices—Opt...
Edge AI and Vision Alliance
 
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
ReSTIR [DI]: Spatiotemporal reservoir resampling for real-time ray tracing ...
revolcs10
 
Securing Account Lifecycles in the Age of Deepfakes.pptx
Securing Account Lifecycles in the Age of Deepfakes.pptx
FIDO Alliance
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
OWASP Barcelona 2025 Threat Model Library
OWASP Barcelona 2025 Threat Model Library
PetraVukmirovic
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Improving Data Integrity: Synchronization between EAM and ArcGIS Utility Netw...
Improving Data Integrity: Synchronization between EAM and ArcGIS Utility Netw...
Safe Software
 

Building reusable components with generics and protocols

  • 2. ! ! #adventofswift One article a day in December until Christmas eve
  • 3. Building reusable components with generics and protocols
  • 5. Goals • Learn how to design code that uses Generics
  • 6. Goals • Learn how to design code that uses Generics • Understand simple generics and associated types
  • 7. Goals • Learn how to design code that uses Generics • Understand simple generics and associated types • Know how to use protocols with associated types with generics
  • 8. Goals • Learn how to design code that uses Generics • Understand simple generics and associated types • Know how to use protocols with associated types with generics • To (not) blow your mind (too much)
  • 9. “I want to have a cache. But it should be able to cache, like, anything.”
  • 10. “I want to have a cache. But it should be able to cache, like, anything.” “And it should have a remote backup, so if the item isn’t available locally, I can take it from the server.”
  • 11. “I want to have a cache. But it should be able to cache, like, anything.” “And it should have a remote backup, so if the item isn’t available locally, I can take it from the server.” “And when the data is taken from the server, the local cache should be updated with the remote version.”
  • 12. “I want to have a cache. But it should be able to cache, like, anything.” “And it should have a remote backup, so if the item isn’t available locally, I can take it from the server.” “And when the data is taken from the server, the local cache should be updated with the remote version.” “And I don’t want to create special cache managers for every type of object or something. Maybe the underlying storage could be specific, but that’s it!”
  • 13. –Me, in the morning. Before I realize what I’m about to get myself into. “I want to have a cache. But it should be able to cache, like, anything.” “And it should have a remote backup, so if the item isn’t available locally, I can take it from the server.” “And when the data is taken from the server, the local cache should be updated with the remote version.” “And I don’t want to create special cache managers for every type of object or something. Maybe the underlying storage could be specific, but that’s it!”
  • 14. $ the appropriate response
  • 15. $ the appropriate response
  • 16. $ my initial response
  • 17. $ my initial response
  • 19. Designing the call site • Figure out how I want to use whatever it is that I’m building
  • 20. Designing the call site • Figure out how I want to use whatever it is that I’m building • This helps to validate your ideas
  • 21. Designing the call site • Figure out how I want to use whatever it is that I’m building • This helps to validate your ideas • Don’t worry about any generics, type names or details yet
  • 22. Designing the call site An easy to use, straightforward API that uses existing data stores and applies the caching logic internally.
  • 24. Designing the implementation And a fairly simple fetch method that tries to find an item in a local store, and uses the remote as a back-up.
  • 25. So far, so good
  • 26. So far, so good But this isn’t the actual thing, is it?
  • 27. So far, so good But this isn’t the actual thing, is it? Oh good, because we were promised generics and protocols and the possibility of getting our minds blown.
  • 28. Step 1 - Generics🎓
  • 29. Step 1 - Generics🎓
  • 30. Step 1 - Generics Generic 🎓
  • 31. Step 1 - Generics🎓
  • 32. Step 1 - Generics Generic Placeholder 🎓
  • 33. Step 1 - Generics Generic Placeholder <YourGeneric> 🎓
  • 34. Step 1 - Generics🎓
  • 35. Step 1 - Generics The Generic defined on the type and the Generic type of the function argument must always be the same type 🎓
  • 36. Step 1 - Generics🎓
  • 37. Step 1 - Generics🎓
  • 38. Step 1 - Generics🎓
  • 39. Step 1 - Generics🎓
  • 40. Step 1 - Generics The compiler will check and enforce that you don’t have a type mismatch 🎓
  • 41. A (kind of) real example%
  • 42. A (kind of) real example% These view models are very similar
  • 43. A (kind of) real example% Much nicer
  • 44. A (kind of) real example% And easy to use!
  • 45. Step 1 - Generics&
  • 46. Step 1 - Generics Our cache backed data store will be generic over T and use a Result of T?, or Optional<T> &
  • 47. Step 1 - Generics Our cache backed data store will be generic over T and use a Result of T?, or Optional<T> &
  • 48. Step 2 - Protocols🎓
  • 49. Step 2 - Protocols🎓
  • 50. Step 2 - Protocols🎓
  • 51. Step 2 - Protocols Protocols don’t have generics like types do. We can’t add T to the declaration and we also can’t use T as a type for methods. 🎓
  • 52. Step 2 - Protocols🎓
  • 53. Step 2 - Protocols🎓 Associated types can be used to define placeholder types.
  • 54. Step 2 - Protocols🎓 We can use these associated types as if they are real types. Objects that conform to this protocol define the associated type.
  • 55. Step 2 - Protocols🎓
  • 56. Step 2 - Protocols🎓 The Swift compiler can infer the “real” type of the associated type when we use it in the conforming type.
  • 57. Step 2 - Protocols🎓 Note that the same type must be used in all places where the associated type was used in the protocol
  • 58. We need to rewind🛑
  • 59. We need to rewind🛑 Currently anything can be our associated type
  • 60. We need to rewind🛑 Currently anything can be our associated type
  • 61. We need to rewind🛑 and that’s a problem
  • 62. We need to rewind🛑 and that’s a problem Why would that be a problem? Wasn’t our goal to cache anything?
  • 63. Step 2 - Protocols🎓
  • 64. Step 2 - Protocols🎓 You can constrain associated types to certain protocols. The compiler will enforce this constraint.
  • 65. Step 2 - Protocols&
  • 66. Step 2 - Protocols&
  • 67. Step 2 - Protocols&
  • 68. Step 2 - Protocols&
  • 69. Step 2 - Protocols&
  • 70. Step 3 - Assemble!🎓
  • 71. Step 3 - Assemble!🎓
  • 72. Step 3 - Assemble!🎓 Very nice.
  • 73. Step 3 - Assemble!🎓 Okay, maybe not so nice…
  • 74. Step 3 - Assemble!🎓
  • 75. Step 3 - Assemble!🎓 We can give names to generics
  • 76. Step 3 - Assemble!🎓 And we can constrain them to protocols
  • 77. Step 3 - Assemble!🎓 And we can now use the LocalStore’s associated type as the success type for our Result.
  • 78. Step 3 - Assemble!&
  • 79. Step 3 - Assemble!& We can now use the local store’s find method to get a Result<Local.StoredObject, Error>
  • 80. Step 3 - Assemble!& If the object was found, the completion closure is called with the Local.StoredObject item that we’ve found.
  • 81. Step 3 - Assemble!& Remote store is used as backup…
  • 82. Step 3 - Assemble!& Think about this line for just a second.
  • 86. Flashback🤔 RemoteStore.TargetObject can’t be used as LocalStore.StoredObject
  • 87. Step 3 - Assemble!🎓 This is a problem…
  • 88. Step 3 - Assemble!&
  • 89. Step 3 - Assemble!&
  • 90. Step 3 - Assemble!& The compiler can now proof and enforce that Local.StoredObject and Remote.TargetObject are the same
  • 91. Step 3 - Assemble!&
  • 92. Step 3 - Assemble!& This is now okay
  • 93. Step 3 - Assemble!& And so is this
  • 94. Step 4 - Using the cache🚀
  • 95. Step 4 - Using the cache🚀
  • 96. Step 4 - Using the cache🚀 • Conforms to LocalStore • LocalStore.StoredObject => User
  • 97. Step 4 - Using the cache🚀 • Conforms to RemoteStore • RemoteStore.TargetObject => User • User is Decodable
  • 98. Step 4 - Using the cache🚀 • Local == ArrayBackedUserStore • Remote == RemoteUserStore • Compiler can infer
  • 99. Step 4 - Using the cache🚀 • We can proof that this is a User
  • 100. Step 4 - Using the cache🚀
  • 101. Step 4 - Using the cache🚀
  • 102. Step 4 - Using the cache🚀
  • 103. Step 4 - Using the cache🚀
  • 104. Step 4 - Using the cache🚀
  • 105. Step 4 - Using the cache🚀
  • 106. Step 4 - Using the cache🚀
  • 107. When is all this useful to know? • Code duplication in Swift is often related to types. Generics can help you clean this up. • You’re most likely to encounter generics in your model/networking layer. • If you want to write frameworks or SDKs.
  • 109. In summary • Figure out how you want to use your code first.
  • 110. In summary • Figure out how you want to use your code first. • Then find out what that means for your implementation.
  • 111. In summary • Figure out how you want to use your code first. • Then find out what that means for your implementation. • If needed, introduce generics and protocols as abstractions.
  • 112. In summary • Figure out how you want to use your code first. • Then find out what that means for your implementation. • If needed, introduce generics and protocols as abstractions. • Constrain your generics and associated types where needed so the compiler can help you.
  • 113. In summary • Figure out how you want to use your code first. • Then find out what that means for your implementation. • If needed, introduce generics and protocols as abstractions. • Constrain your generics and associated types where needed so the compiler can help you. • Generics can help you limit code duplication.
  • 115. Thank you Questions are always welcome