Why I Chose Core Data Over SwiftData for Hive Notes
SwiftData has cleaner syntax, but Core Data has two decades of reliability. Here's why I chose Core Data for a complex beekeeping app with 15 entities.
If you're looking for a quick fix, then I don't have anything to offer you. If you want to become a better Swift developer, then have a seat and let me share with you what I know.
SwiftData has cleaner syntax, but Core Data has two decades of reliability. Here's why I chose Core Data for a complex beekeeping app with 15 entities.
AI migrations convert syntax but miss modernization opportunities. Learn why "working code" isn't the same as modern Swift and what it costs long-term.
AI-migrated Swift code compiles perfectly but breaks in production. Learn the five hidden runtime issues in converted codebases, from threading bugs to Unicode edge cases, and why compilation success isn't enough.
Picture this scenario: a freshly migrated app is in production, users are happy, and then the crash reports start rolling in. Not sporadically. Consistently. Every user who tries to view their profile is welcomed with a crash.
A few years ago, Apple added support for detecting potential issues at runtime. Runtime issues show up as purple issues in Xcode's Issues Navigator. They are easy to miss or ignore, but they are just as important as errors at compile time.
In the previous video, we used the Swift error breakpoint to suspend the process of the app if an error is thrown in your code or the code of a library or framework. The exception breakpoint works in a similar way. The difference, as you may have guessed, is that the debugger suspends the process of the app if an exception is thrown.
Error handling is a key aspect of the Swift language. In several ways errors in Swift are similar to exceptions in Objective-C and C++. Both errors and exceptions indicate that something didn't go as planned. The Swift error and exception breakpoints are useful to debug scenarios in which errors or exceptions are thrown.
Earlier in this course, we briefly explored the types of breakpoints you can use in Xcode. In the previous video, we focused on file and line breakpoints. This video zooms in on symbolic breakpoints.
When you are debugging a complex problem, you quickly end up with dozens of breakpoints scattered across your project or workspace. I would like to start this video by showing you how you can stay on top of the breakpoints in a project or workspace.
In the previous video, you learned what a breakpoint is and what types of breakpoints Xcode supports. In this video, we step through code using a breakpoint and the debug bar we explored earlier in this course.
Breakpoints are indispensable for debugging problems in a software project. Debugging an app with breakpoints can seem complex at first, but it isn't difficult once you understand what is going on. While the underlying concept of debugging with breakpoints is simple, you can make it as complex as you want to fit your needs.
Xcode offers developers a mature development environment with a powerful debugger. Under the hood, Xcode's debugging tools take advantage of LLDB, the debugger of the LLVM project. It isn't necessary to have a deep understanding of LLDB or LLVM to make use of Xcode's debugging tools, but it certainly doesn't hurt to become familiar with LLDB or LLVM.
Everyone makes mistakes, and developers are no different. As a developer, you spend a significant portion of your time debugging the code you write. It is an inextricable aspect of software development. Some bugs are easy to find, while others can make you scratch your head.
I'd like to end this series by taking advantage of the recently introduced Observable macro. The changes we need to make are small and focused, but we also run into a few issues. Let's get started.
In this episode, we finish the unit test we started in the previous episode. Even though the implementation of the addLocation(with:) method of the AddLocationViewModel class isn't overly complex, writing a unit test for it is quite the challenge. Let's continue where we left off.
In this episode, we continue where we left off in the previous episode, that is, writing unit tests for the AddLocationViewModel class. This episode is an important one because it illustrates the impact asynchronous code can have on the unit tests you write.
In the previous episode, we wrote unit tests for a simple view model, the AddLocationCellViewModel struct. In this episode, we take it up a notch and write unit tests for a complex view model. We take the AddLocationViewModel class as an example.
One of the key benefits of the Model-View-ViewModel pattern is improved testability. It isn't possible to write unit tests for the SwiftUI views we created, but we can unit test the view models that drive those views. The good news is that writing unit tests for a well-designed view model isn't difficult.
Discover why gut health matters for developers. Learn how eating whole foods, focusing on fiber diversity, and using tools like Plant Power can boost your energy, focus, and productivity.
Offering a subscription product in your application involves more than integrating with Apple's StoreKit framework. You need to set up subscription products in App Store Connect, keep track of the user's subscription status, and restrict access to the content or features that are exclusive to subscribers. Things get even more complicated if your application offers multiple tiers or is available on…
We hit a roadblock in the previous episode. The CurrentConditionsViewModel struct needs access to a Store object, but it is tedious to pass a Store object from one view model to the next. In this episode, we use a dependency injection library, Swinject, to make this much less of a problem.
The last feature we need to add is the ability to delete locations. The changes we need to make are small, but there is a problem we need to address. Let's start by adding a button to the CurrentConditionsView.
The LocationView is always in one of two states, fetching weather data or displaying weather data. It is the LocationView itself that implicitly defines these states and that is limiting. Not only is it limiting, we cannot write unit tests for the states of the LocationView. In this episode, I show you a solution that is testable and extensible.
The LocationView still displays stub data. That is something we change in this episode. The LocationViewModel struct is responsible for fetching the weather data the LocationView displays. It uses that weather data to create view models for the CurrentConditionsView and the ForecastView.
In this episode, we refactor the ForecastViewModel struct and the ForecastCellViewModel struct. The ForecastViewModel struct drives the ForecastView, the bottom section of the LocationView. Let's get to work.
In this episode, we refactor the CurrentConditionsViewModel struct. Remember that the CurrentConditionsViewModel struct drives the CurrentConditionsView, the top section of the LocationView. The changes we need to make are small.
In yesterday's episode, I wrote about protecting your application's secretes with a proxy server. In today's episode, I show you how to set up a proxy server with Swift and Vapor.
Most of the services your application interacts with require authentication. Authentication through a secret, an API key or a client secret, is a commonly used method. Your application includes the secret in the request it sends to the service. That is only possible if your application has access to the secret at runtime.
In the previous episode, we used the MeasurementFormatter class to format the raw values the Clear Sky API returns. This is convenient and we use the MeasurementFormatter class several more times in the next few episodes. In this episode, we create an elegant API that wraps around the MeasurementFormatter API to avoid code duplication.
With the WeatherService protocol in place, we can refactor the view models that need to provide their views with weather data. In this episode, we focus on the LocationCell by refactoring the LocationCellViewModel class.
In the previous episode, we hard-coded the base URL and the API key of the Clear Sky API in the WeatherClient class. I'm not a fan of hard-coding configuration details. In this episode, we explore an alternative approach.
In this episode, we add the ability to fetch weather data from the Clear Sky API and decode a WeatherData object from the API response. We apply a pattern that should feel familiar by now.
It is time to focus on one of the core aspects of the weather application we are building, fetching and displaying weather data. Thunderstorm displays placeholder data for the time being. That is something we change in this and the next episodes.
Being a programmer myself, I know how challenging it can be to find the perfect gift for a fellow coder. Programmers are often quirky with peculiar interests. Finding a gift that speaks to their passions can be, well, challenging. The good news is that there are plenty of options to delight any coder, whether they are a seasoned professional or just starting out.
The user's defaults database acts as the store of the weather application we are building. That is fine, but most objects shouldn't be aware of that implementation detail. The LocationsViewModel and AddLocationViewModel classes are tightly coupled to the UserDefaults class, but that isn't necessary. In this episode, we decouple the LocationsViewModel and AddLocationViewModel classes from the…
In this episode, we revisit the addLocation(with:) method of the AddLocationViewModel class. In that method, the view model stores the location the user selected in the user's defaults database.
The final keyword in Swift is often ignored or overlooked. That isn't surprising as it isn't immediately obvious what the benefits are of annotating a class, method, or property with the final keyword. In this episode, you learn about the obvious and less obvious benefits of diligently marking a class, method, or property as final.
You may remember that the LocationsView displays a static list of locations. We need to change that if we want to put the AddLocationView to use. We keep it simple and store the list of locations in the user's defaults database. Let's get to work.
As developers, we spend countless hours glued to our screens, deeply immersed in lines of code. While the thrill of solving tough problems and building great software is undeniable, it's crucial to step away periodically and reconnect with something equally complex and rewarding. Nature.