SlideShare a Scribd company logo
1 of 51
Download to read offline
@BGONDIM
@BBILESCKY
ESTADODEFINIÇÃO, MANIPULAÇÃO E MANUTENÇÃO
CLASSES
> SIDE EFFECTS
VALUE TYPESTO THE RESCUE
IMUTABILIDADE
MUTÁVEL
struct Credential {
let username: String
let password: String
}
extension Credential {
func byChanging(username: String)-> Credential {
let newCredential = Credential(username: username, password: self.password)
return newCredential
}
func byChanging(password: String)-> Credential {
let newCredential = Credential(username: self.username, password: password)
return newCredential
}
}
struct Contact {
let firstName: String
let lastName: String
let email: String
let cellPhone: String?
let phone: String?
let birthdate: Date
let bloodType: BloodType
let hairColor: Color
let eyeColor: Color
let height: Int
let weight: Int
let nickname: String?
let spouse: Contact?
}
LET X VAR
FONTE ÚNICA DA
VERDADE
WILLSET
& DIDSET
SE A MUDANÇA
DE UM VALOR
AFETA OUTRO VALOR
ATUALIZE-O SEMPRE.
NÃO DEIXE PARA
O PROGRAMADORELE PODE NÃO SE LEMBRAR AMANHA OU DAQUI A 3 MESES
ENUM
DEFINIÇÃO CLARA
POSSIBILIDADES
ASSOCIATED VALUES
CASO PRÁTICO
APLICATIVO QUE EXIBE UMA LISTA DE
REPOSITÓRIOS DO GITHUB
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
var repositories: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return repositories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "", for: indexPath)
return cell
}
}
O QUE SIGNIFICA
REPOSITORIES.COUNT == 0
NENHUM REQUEST RETORNOU DADOS AINDA
É O ESTADO INICIAL DA TELA
NÃO ENCONTRAMOS NENHUM DADO
OCORREU UM ERRO E NÃO FOI POSSÍVEL RECUPERAR DADOS
SOLUÇÕES?
VARIÁVEIS DE CONTROLE
private var listIsEmpty: Bool
private var currentRequest: Request?
NOVA FEATURE
ADICIONAR VIEWS PARA
BLANK/ERROR/LOADING
private var listIsEmpty: Bool
private var currentRequest: Request?
private var loadError: Error?
private var isLoading: Bool {
return currentRequest != nil
}
enum ViewState {
case willLoadInitialData
case loaded(repos:[String])
case loading(Request, oldRepos:[String])
case loadedWithError(repos:[String], Error)
case empty
}
var currentState: ViewState = .empty
var currentState: ViewState = .empty {
didSet {
render(old: oldState, newState: currentState)
}
}
var currentState: ViewState = .empty {
willSet {
handle(newState: currentState)
}
}
FEATURE REQUEST:
SELEÇÃO DE REPOSITÓRIO
enum ViewState {
case willLoadInitialData
case loaded(repos:[String], selected: String?)
case loading(Request, oldRepos:[String], selected: String?)
case loadedWithError(repos:[String], Error, selected: String?)
case empty
}
FEATURE REQUEST:
CANCELAR REQUEST ATUAL
extension ViewState {
var currentRequest: Request? {
guard let .loading(request, _, _) else { return nil }
return request
}
}
viewState.currentRequest?.cancel()
FEATURE REQUEST:
OFFLINE SUPPORT
enum ViewState {
case willLoadInitialData
case offline(repos:[String], changes: [Change], selected: String?)
case loaded(repos:[String], selected: String?)
case loading(Request, oldRepos:[String], selected: String?)
case loadedWithError(repos:[String], Error, selected: String?)
case empty
}
STATE CONTAINER
PERMITE MULTIPLAS ASSINATURAS
PARA MUDANÇAS DE VALOR
class State<Type> {
let key: String
var value: Type {
return __value
}
private var __value: Type
init(_ defaultValue: Type, key: String) {
self.__value = defaultValue
self.key = key
}
public func modify(_ value: Type) {
__value = value
didModify()
}
func didModify() {
}
}
protocol StateListener : AnyObject {
func stateModified<T>(_ state: State<T>)
}
protocol OptionalType {
var isNil: Bool { get }
}
extension Optional : OptionalType {
public var isNil: Bool {
return self == nil
}
}
class MonitoredState<Type> : State<Type> {
fileprivate let listeners: NSHashTable<AnyObject>
override init(_ defaultValue: Type, key: String) {
self.listeners = NSHashTable<AnyObject>.weakObjects()
super.init(defaultValue, key: key)
}
var allListeners: [StateListener] {
return self.listeners.allObjects.map({ $0 as? StateListener }).flatMap({ $0 })
}
override func didModify() {
super.didModify()
let allListeners = self.allListeners
let state = self
for l in allListeners {
l.stateModified(state)
}
}
func attach(listener: StateListener) {
self.listeners.add(listener as AnyObject)
}
}
class UserDefaultsState<Type> : MonitoredState<Type>, StateListener {
let innerState: MonitoredState<Type>
init(state: MonitoredState<Type>) {
self.innerState = state
super.init(state.value, key: state.key)
let existingValue = UserDefaults.standard.object(forKey: key)
if let existing = existingValue as? Type {
state.modify(existing)
} else if let data = existingValue as? Data, let decoded = NSKeyedUnarchiver.unarchiveObject(with: data) as? Type {
state.modify(decoded)
}
if let monitoredState = state as? MonitoredState<Type> {
monitoredState.attach(listener: self)
}
}
override var value: Type {
return innerState.value
}
override func modify(_ value: Type) {
innerState.modify(value)
}
func stateModified<T>(_ state: State<T>) {
self.didModify()
}
override func didModify() {
super.didModify()
let val = self.value
if let val = val as? OptionalType, val.isNil {
UserDefaults.standard.removeObject(forKey: self.key)
print("Removed (self.key) from UserDefaults")
} else if let val = val as? NSCoding {
UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: val), forKey: self.key)
print("Saved (self.key) to UserDefaults")
} else {
UserDefaults.standard.set(val, forKey: self.key)
print("Saved (self.key) to UserDefaults")
}
UserDefaults.standard.synchronize()
}
}
class HistoryState<Type>: MonitoredState<Type>, StateListener {
let innerState: MonitoredState<Type>
private var __history: [Type] = []
public var history: [Type] {
return __history
}
override var value: Type {
return innerState.value
}
override func modify(_ value: Type) {
innerState.modify(value)
}
func stateModified<T>(_ state: State<T>) {
self.didModify()
}
init(state: MonitoredState<Type>) {
self.innerState = state
super.init(state.value, key: state.key)
if let monitoredState = state as? MonitoredState<Type> {
monitoredState.attach(listener: self)
}
}
override func didModify() {
super.didModify()
__history.append(self.value)
}
}
let appCount = MonitoredState<Int>(0, key: "appCount")
PERMITE A
PERSISTÊNCIA
DOS VALORES
let userDefaultsAppCount = UserDefaultsState(state: appCount)
TESTESHISTÓRICO DE ESTADOS
let historyAppCount = HistoryState(state: userDefaultsAppCount)
MAIS INFORMAÇÕES
MODELLING STATE IN SWIFT POR @JOHNSUNDELL
STATE CONTAINERS IN SWIFT POR
OBRIGADO

More Related Content

What's hot

Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product DevelopmentTom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product DevelopmentVincenzo Barone
 
[Swift] Chain of Responsibility
[Swift] Chain of Responsibility[Swift] Chain of Responsibility
[Swift] Chain of ResponsibilityBill Kim
 
jQuery1.2.cheatsheet.v1.0
jQuery1.2.cheatsheet.v1.0jQuery1.2.cheatsheet.v1.0
jQuery1.2.cheatsheet.v1.0guest644d1d
 
Informasjonsintegrasjon – hva er utfordringene
Informasjonsintegrasjon – hva er utfordringeneInformasjonsintegrasjon – hva er utfordringene
Informasjonsintegrasjon – hva er utfordringeneStian Danenbarger
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented JavascriptDaniel Ku
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5Martin Kleppe
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UIRebecca Murphey
 

What's hot (11)

Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 
Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product DevelopmentTom Lazar   Using Zope3 Views And Viewlets For Plone 3.0 Product Development
Tom Lazar Using Zope3 Views And Viewlets For Plone 3.0 Product Development
 
[Swift] Chain of Responsibility
[Swift] Chain of Responsibility[Swift] Chain of Responsibility
[Swift] Chain of Responsibility
 
jQuery1.2.cheatsheet.v1.0
jQuery1.2.cheatsheet.v1.0jQuery1.2.cheatsheet.v1.0
jQuery1.2.cheatsheet.v1.0
 
Understanding redux
Understanding reduxUnderstanding redux
Understanding redux
 
Informasjonsintegrasjon – hva er utfordringene
Informasjonsintegrasjon – hva er utfordringeneInformasjonsintegrasjon – hva er utfordringene
Informasjonsintegrasjon – hva er utfordringene
 
Dependency injection in Scala
Dependency injection in ScalaDependency injection in Scala
Dependency injection in Scala
 
Object-oriented Javascript
Object-oriented JavascriptObject-oriented Javascript
Object-oriented Javascript
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
 
jQuery
jQueryjQuery
jQuery
 

Similar to Controle de estado

JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the ASTJarrod Overson
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scalaparag978978
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesCody Yun
 
Scaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkitScaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkitBojan Babic
 
ActionScript3 collection query API proposal
ActionScript3 collection query API proposalActionScript3 collection query API proposal
ActionScript3 collection query API proposalSlavisa Pokimica
 
Scala in practice
Scala in practiceScala in practice
Scala in practicepatforna
 
Unidirectional Data Flow with Reactor
Unidirectional Data Flow with ReactorUnidirectional Data Flow with Reactor
Unidirectional Data Flow with ReactorJason Larsen
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kirill Rozov
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyMartin Zapletal
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using RoomNelson Glauber Leal
 

Similar to Controle de estado (20)

The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
Introduction kot iin
Introduction kot iinIntroduction kot iin
Introduction kot iin
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and Classes
 
Scaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkitScaling modern JVM applications with Akka toolkit
Scaling modern JVM applications with Akka toolkit
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
ActionScript3 collection query API proposal
ActionScript3 collection query API proposalActionScript3 collection query API proposal
ActionScript3 collection query API proposal
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Unidirectional Data Flow with Reactor
Unidirectional Data Flow with ReactorUnidirectional Data Flow with Reactor
Unidirectional Data Flow with Reactor
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data Efficiently
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 

Recently uploaded

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 

Recently uploaded (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 

Controle de estado

  • 6. struct Credential { let username: String let password: String }
  • 7. extension Credential { func byChanging(username: String)-> Credential { let newCredential = Credential(username: username, password: self.password) return newCredential } func byChanging(password: String)-> Credential { let newCredential = Credential(username: self.username, password: password) return newCredential } }
  • 8. struct Contact { let firstName: String let lastName: String let email: String let cellPhone: String? let phone: String? let birthdate: Date let bloodType: BloodType let hairColor: Color let eyeColor: Color let height: Int let weight: Int let nickname: String? let spouse: Contact? }
  • 12. SE A MUDANÇA DE UM VALOR AFETA OUTRO VALOR
  • 14. NÃO DEIXE PARA O PROGRAMADORELE PODE NÃO SE LEMBRAR AMANHA OU DAQUI A 3 MESES
  • 15. ENUM
  • 19. APLICATIVO QUE EXIBE UMA LISTA DE REPOSITÓRIOS DO GITHUB
  • 20. class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet var tableView: UITableView! var repositories: [String] = [] override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return repositories.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "", for: indexPath) return cell } }
  • 22. NENHUM REQUEST RETORNOU DADOS AINDA É O ESTADO INICIAL DA TELA NÃO ENCONTRAMOS NENHUM DADO OCORREU UM ERRO E NÃO FOI POSSÍVEL RECUPERAR DADOS
  • 25. private var listIsEmpty: Bool private var currentRequest: Request?
  • 26. NOVA FEATURE ADICIONAR VIEWS PARA BLANK/ERROR/LOADING
  • 27. private var listIsEmpty: Bool private var currentRequest: Request? private var loadError: Error? private var isLoading: Bool { return currentRequest != nil }
  • 28. enum ViewState { case willLoadInitialData case loaded(repos:[String]) case loading(Request, oldRepos:[String]) case loadedWithError(repos:[String], Error) case empty }
  • 30. var currentState: ViewState = .empty { didSet { render(old: oldState, newState: currentState) } }
  • 31. var currentState: ViewState = .empty { willSet { handle(newState: currentState) } }
  • 33. enum ViewState { case willLoadInitialData case loaded(repos:[String], selected: String?) case loading(Request, oldRepos:[String], selected: String?) case loadedWithError(repos:[String], Error, selected: String?) case empty }
  • 35. extension ViewState { var currentRequest: Request? { guard let .loading(request, _, _) else { return nil } return request } } viewState.currentRequest?.cancel()
  • 37. enum ViewState { case willLoadInitialData case offline(repos:[String], changes: [Change], selected: String?) case loaded(repos:[String], selected: String?) case loading(Request, oldRepos:[String], selected: String?) case loadedWithError(repos:[String], Error, selected: String?) case empty }
  • 40. class State<Type> { let key: String var value: Type { return __value } private var __value: Type init(_ defaultValue: Type, key: String) { self.__value = defaultValue self.key = key } public func modify(_ value: Type) { __value = value didModify() } func didModify() { } }
  • 41. protocol StateListener : AnyObject { func stateModified<T>(_ state: State<T>) } protocol OptionalType { var isNil: Bool { get } } extension Optional : OptionalType { public var isNil: Bool { return self == nil } }
  • 42. class MonitoredState<Type> : State<Type> { fileprivate let listeners: NSHashTable<AnyObject> override init(_ defaultValue: Type, key: String) { self.listeners = NSHashTable<AnyObject>.weakObjects() super.init(defaultValue, key: key) } var allListeners: [StateListener] { return self.listeners.allObjects.map({ $0 as? StateListener }).flatMap({ $0 }) } override func didModify() { super.didModify() let allListeners = self.allListeners let state = self for l in allListeners { l.stateModified(state) } } func attach(listener: StateListener) { self.listeners.add(listener as AnyObject) } }
  • 43. class UserDefaultsState<Type> : MonitoredState<Type>, StateListener { let innerState: MonitoredState<Type> init(state: MonitoredState<Type>) { self.innerState = state super.init(state.value, key: state.key) let existingValue = UserDefaults.standard.object(forKey: key) if let existing = existingValue as? Type { state.modify(existing) } else if let data = existingValue as? Data, let decoded = NSKeyedUnarchiver.unarchiveObject(with: data) as? Type { state.modify(decoded) } if let monitoredState = state as? MonitoredState<Type> { monitoredState.attach(listener: self) } } override var value: Type { return innerState.value } override func modify(_ value: Type) { innerState.modify(value) } func stateModified<T>(_ state: State<T>) { self.didModify() } override func didModify() { super.didModify() let val = self.value if let val = val as? OptionalType, val.isNil { UserDefaults.standard.removeObject(forKey: self.key) print("Removed (self.key) from UserDefaults") } else if let val = val as? NSCoding { UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: val), forKey: self.key) print("Saved (self.key) to UserDefaults") } else { UserDefaults.standard.set(val, forKey: self.key) print("Saved (self.key) to UserDefaults") } UserDefaults.standard.synchronize() } }
  • 44. class HistoryState<Type>: MonitoredState<Type>, StateListener { let innerState: MonitoredState<Type> private var __history: [Type] = [] public var history: [Type] { return __history } override var value: Type { return innerState.value } override func modify(_ value: Type) { innerState.modify(value) } func stateModified<T>(_ state: State<T>) { self.didModify() } init(state: MonitoredState<Type>) { self.innerState = state super.init(state.value, key: state.key) if let monitoredState = state as? MonitoredState<Type> { monitoredState.attach(listener: self) } } override func didModify() { super.didModify() __history.append(self.value) } }
  • 45. let appCount = MonitoredState<Int>(0, key: "appCount")
  • 47. let userDefaultsAppCount = UserDefaultsState(state: appCount)
  • 49. let historyAppCount = HistoryState(state: userDefaultsAppCount)
  • 50. MAIS INFORMAÇÕES MODELLING STATE IN SWIFT POR @JOHNSUNDELL STATE CONTAINERS IN SWIFT POR