Prepping For A SwiftUI Future
Veronica Ray, Senior Software Engineer at Compass
Slide 2
Slide 2 text
Flux
Missing features
Functional reactive programming
MVVM
Combine
Testing
Declarative
Black box
Less code to write
Better performance
App architecture
SwiftUI
Fun
Composable Architecture
Interoperability
Missing documentation
Collaboration with designers
Slide 3
Slide 3 text
Preparing Your Codebase
Slide 4
Slide 4 text
What App Architecture Is Best For SwiftUI?
• MVVM
• Flux
• The Composable Architecture
Slide 5
Slide 5 text
Animal Crossing Creators
• Creators post IDs online that you use to download outfits
• There’s no way to save these IDs in the game
• Animal Crossing Creators allows you to save your favorite creators
Slide 6
Slide 6 text
Hat tip to
MA-6549-3814-5086
for this amazing
outfit!
Slide 7
Slide 7 text
Why Use MVVM?
• The “default” choice for SwiftUI
• Many UIKit apps already use this successfully
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
Managing State
Slide 10
Slide 10 text
Why Use Flux?
• Small amount of code needed
• 3rd party libraries for it are lightweight
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
Why Use Composable Architecture?
• Inspired by Flux, but more opinionated and heavyweight
• Open source library with great documentation and examples
• Example apps covering many domains
• Videos showing thought process
Slide 13
Slide 13 text
Flux Pain Points
Slide 14
Slide 14 text
Views Contain The Data
Needed To Render Themselves
And Their Children
Slide 15
Slide 15 text
No content
Slide 16
Slide 16 text
var body: some View {
WithViewStore(self.store.scope(state: \.view)) { viewStore in
A Pragmatic Approach
• Don’t need a big rewrite of existing app
• Take advantage of the faster development speed of SwiftUI in new projects
• Need to master the art of interoperability with UIKit
private let backButton = UIHostingController(rootView: SearchBarBackButton())
Slide 32
Slide 32 text
Using UIKit Within SwiftUI Is
NOT Easy
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
Step 1: UIViewRepresentable
Slide 35
Slide 35 text
public struct LabelRepresentation: UIViewRepresentable {
var textColor: UIColor
var font: UIFont
var text: String
public func makeUIView(context: UIViewRepresentableContext) -> Label {
let label = Label()
label.textColor = textColor
label.font = font
return label
}
public func updateUIView(_ uiView: Label, context: UIViewRepresentableContext) {
uiView.text = text
}
}
Slide 36
Slide 36 text
public struct LabelRepresentation: UIViewRepresentable {
var textColor: UIColor
var font: UIFont
var text: String
public func makeUIView(context: UIViewRepresentableContext) -> Label {
let label = Label()
label.textColor = textColor
label.font = font
return label
}
public func updateUIView(_ uiView: Label, context: UIViewRepresentableContext) {
uiView.text = text
}
}
Slide 37
Slide 37 text
public struct LabelRepresentation: UIViewRepresentable {
var textColor: UIColor
var font: UIFont
var text: String
public func makeUIView(context: UIViewRepresentableContext) -> Label {
let label = Label()
label.textColor = textColor
label.font = font
return label
}
public func updateUIView(_ uiView: Label, context: UIViewRepresentableContext) {
uiView.text = text
}
}
Slide 38
Slide 38 text
public struct LabelRepresentation: UIViewRepresentable {
var textColor: UIColor
var font: UIFont
var text: String
public func makeUIView(context: UIViewRepresentableContext) -> Label {
let label = Label()
label.textColor = textColor
label.font = font
return label
}
public func updateUIView(_ uiView: Label, context: UIViewRepresentableContext) {
uiView.text = text
}
}
Slide 39
Slide 39 text
Step 2: Add UIRepresentable
View To SwiftUI View
Slide 40
Slide 40 text
public struct PageIndicatorView: View {
@ObservedObject var model: PageIndicatorModel
public var body: some View {
LabelRepresentation(textColor: .white,
font: .compassSansMedium(12),
text: model.text)
}
}
Summary
• Decide now if you want to adopt a new app architecture
• When you can, write all new code in SwiftUI
• Adopt SwiftUI and Combine together unless you have a great reason to not use
Combine
• Do interoperability spikes in your production app