Upload
john-sundell
View
282
Download
0
Embed Size (px)
Citation preview
@JOHNSUNDELL
BUILDING COMPONENT-DRIVEN UIS
John Sundell Lead iOS Developer, Spotify
! "
! "#
CocoaPods/Carthage
Fastlane
Swift
Protocol oriented programming
Model-View-ViewModel
Promises / Operations / Rx
UI
// MARK: - UITableViewDataSource func numberOfSections(in tableView: UITableView) -> Int { return 2 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 0 { return model.unreadMessages.count } return model.readMessages.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "message", for: indexPath) let message: Message if indexPath.section == 0 { message = model.unreadMessages[indexPath.row] } else { message = model.readMessages[indexPath.row] } cell.textLabel?.text = message.subject cell.detailTextLabel?.text = "From: \(message.sender)" return cell }
UITableViewDelegate
UITableViewDataSource
Caching
UIViewController subclass
JSON parsing
Integrate view controller with the rest of the app
Setup UITableView
Register UITableViewCell classUITableViewCell subclass
Handle network errors
Handle slow connections
OfflinePerform HTTP request
View Model
City Model
BACKEND
Render state
[ Image(“Tokyo”), Image(“Gothenburg”), Row(“Berlin”, “Germany”), Row(“Beijing”, “China”), Row(“Paris”, “France”), Row(“San Francisco”, “USA”), User(“Julia”), User(“Mathew”), User(“Caroline”), User(“David”), Row(“Athens”, “Greece”), Row(“Oslo”, “Norway”), Row(“Stockholm”, “Sweden”)
]
UI = fn(state)
1. SHARED DATA MODEL
struct Image { var url: URL }
struct City { var name: String var country: String }struct User {
var name: String var imageUrl: URL }
ComponentModel
ComponentModel
ComponentModel
ViewModel
struct { var title: String var subtitle: String var imageUrl: URL ... }
ComponentModel
2. PROTOCOL-ORIENTED VIEWS
Components
UICollectionView
protocol Component {var view: UIView? { get }
func loadView()
}func configure(withModel: ComponentModel)
var preferredViewSize: CGSize { get }var layoutTraits: [LayoutTrait] { get }
UICollectionViewLayout
3. A DECLARATIVE API
$
Logic to load content Respond to Interactions
COMPONENTSCOMPONENT
MODELS
CONTENT OPERATIONSViewModelBuilder Content
BACKEND
MODELS
COMPONENTSCOMPONENT
MODELSCONTENT
OPERATIONS
DECLARERENDER
1. SHARED DATA MODEL
2. PROTOCOL-ORIENTED VIEWS
3. A DECLARATIVE API
THE HUB FRAMEWORK
DEMO
OPEN SOURCE! %
GITHUB.COM/JOHNSUNDELL
@JOHNSUNDELL