Issue #39
👨🎨 Implementing Views Using Mock Data 🚧
The #1 Padel Score Tracker Companion
With seamless point counting on your Apple Watch, Padel Time ensures precision and eliminates disputes, leaving you to focus on the game. You just need to raise your arm and click on the winning team on each point, nothing else.
Welcome to issue #39 of the iOS Coffee Break Newsletter 📬 and to the 3rd issue of the "Building a Newsletter App" series!
Last week, we covered how to create and use Protocols in Swift and introduced an IssuesLiveRepository
that performs the work of a real external dependency within our app.
This week, I am introducing additional implementations of the IssuesRepository
protocol, tailored for different use cases such as mocking and testing.
The Plan
As part of this, I will implement 3 additional versions of the IssuesRepository
protocol, each designed to serve as a mock for different scenarios within our IssuesView
.
IssuesSuccessMockRepository
to handle scenarios where our mocked dependency returns data.IssuesEmptyRepository
to handle scenarios where our mocked dependency doesn't return data.IssuesFailureMockRepository
to handle scenarios where our mocked dependency returns an error.
Creating Additional Instances of the IssuesRepository
Let's first create an IssuesSuccessMockRepository
class that returns an array of sample issues.
class IssuesSuccessMockRepository: IssuesRepository {
func getIssues() async throws -> [Issue] {
return Issue.sample
}
}
Next, I am creating IssuesEmptyMockRepository
for the scenario that displays no issues data. Here I want to return an empty array.
class IssuesEmptyMockRepository: IssuesRepository {
func getIssues() async throws -> [Issue] {
return []
}
}
Finally, I am creating IssuesFailureMockRepository
and here, I am throwing an exception.
class IssuesFailureMockRepository: IssuesRepository {
func getIssues() async throws -> [Issue] {
throw APIError.unknownError
}
}
Making Use of our Mocks
Using our IssuesView
from previous discussions as an example, I can use the #preview
macro to see how the view appears with the 3 newly implemented versions:
struct IssuesView: View {
@State var vm: IssuesViewModel
init(vm: IssuesViewModel = IssuesViewModel()) {
self.vm = vm
}
var body: some View {
NavigationStack {
List(vm.issues) { issue in
IssueRowView(issue: issue)
}
.navigationTitle("Issues")
.overlay {
if vm.issues.isEmpty {
ContentUnavailableView(
"No Issues",
systemImage: "books.vertical.fill",
description: Text("No issues have been found.")
)
}
}
.alert(isPresented: $vm.hasError, error: vm.error) {
Button("Retry") {
Task {
await vm.getIssues()
}
}
}
.task {
await self.vm.getIssues()
}
}
}
}
#Preview("Happy Path") {
IssuesView(
vm: IssuesViewModel(
issuesRepository: IssuesSuccessMockRepository()
)
)
}
#Preview("Empty Path") {
IssuesView(
vm: IssuesViewModel(
issuesRepository: IssuesEmptyMockRepository()
)
)
}
#Preview("Unhappy Path") {
IssuesView(
vm: IssuesViewModel(
issuesRepository: IssuesFailureMockRepository()
)
)
}
Here is the output of the IssuesView
with the 3 previews:
🤝 Wrapping Up
With that, you can see the advantages of using mocks to design views for different scenarios. Keep this approach in mind when writing your code to ensure it remains flexible and scalable.
Mock data can also be incredibly useful in testing, enabling us to write tests a lot easier, and run them faster in a more predictable way as I plan to show you on future issues! Stay tuned!
CURATED FROM THE COMMUNITY
🐼 Freeing up space on your Mac
If you are an iOS developer, chances are you have run into storage issues on your machine at some point — thank you Xcode!
This week, Manu put together a great guide on manually freeing up space on your Mac. While there are external tools that can handle this for you, I promise it is an interesting read, even if you are just curious about how Xcode eats up your storage.
🧘♂️ How to automate perfect screenshots for the Mac App Store
Jesse recently explored ways to automate macOS screenshots, finding far fewer options compared to iOS.
He put his findings into an article, detailing his workflow for generating Mac app screenshots with minimal manual effort. If you have faced the same challenge, be sure to check it out!
🔎 Profiling apps using Instruments
Not quite sure how to use Apple's Instruments tool yet?
Apple just released an in-depth, 1.5-hour tutorial on profiling apps with Instruments — an invaluable resource for anyone looking to get started! If you are interested but unsure where to begin, this is the perfect guide. It is definitely on my watch list!