The lack of recent blog posts doesn’t mean I’ve been idle for the last ten days. Oh no. Having read through Core Data (Quick Start) in SwiftUI from Big Mountain Studio, I figured that it was about time that I put some of Mark’s teachings into practice.
I’ve had an idea in my head for an app for the last couple of months (after I abandoned my initial idea into the bin of “no one would be interested in this one”), and I know it’s going to rely heavily on Core Data. I don’t want to get bogged down all with the available options right now, but I would like to figure out how much I’ve understood from Mark’s book and previous lessons from CWC+. So, I spent a couple of days adapting Mark’s teachings into something I could use for my own data, Data Models, and Entities.
Everything went pretty well, with my mock data showing up as it should, and I was pleased that it all made some kind of sense to me.
Around this time, Mark from Big Mountain Studio asked if I intended to go further into Core Data – and, of course, I did and do – and he invited me to offer feedback on his follow-up book, and this is where we’re at now.
Core Data Mastery in SwiftUI begins with the 75 pages we’ve already read as Core Data (Quick Start) in SwiftUI. You have read that one, right? No? Okay, you can start on page 1, but I’m going straight to page 76…
Last time out, we reached as far as displaying data after which Mark now takes us through the use of @FetchRequest
for sorting and filtering (using the oddly-named “NSPredicate
“). The latter of these includes setting up Fetch Requests within the data model – something we touched on briefly when working on the CWC+ Database lessons.
“Filtering with Searchable” is that clever bit in apps where you can begin typing a search phrase, and we use NSPredicate
to limit the list of search results. I’ll be using that quite a bit! Did you know you can also animate the limiting of the search results? Pretty cool.
We can also use @SectionedFetchRequest
, helpfully allowing us to group our results into separate sections. Chapters I’ll be returning to include “Constraints”, and “Default Values”, together with “Undo and Redo”, but what most interests me is the 50+ pages of “Relationships”. I’ve done quite a bit of work with Relational Databases in the past, both with SQL web-work and the years prior to that, so I “get” what they are – it’s only the implementation in SwiftUI that baffles me.
Core Data isn’t SQL, and the hardest time I’m having is “unlearning” what I’ve been using for many years. There are similarities, of course, but it’s in the differences that minor roadbumps can turn into massive hurdles.
Thanks to Mark’s book, I’ve been able to work on my code alongside his teachings so that, when things go wrong, I can drill down to every aspect and see what I’ve done wrong (or haven’t done right). So far, this has been proving beneficial.
Core Data Mastery in SwiftUI takes two object entities (a list of car manufacturers, and a list of cars), links them together, and Mark takes us through code to manipulate how to display them, create new entities, update, and delete entities. I’m using the same process for my app, but I’m attempting to work in a third entity. I’m part way into that now, as I try to visualise in my head what the relationships actually are before I make a hash of the code!
Another little addition I’ve added to my app is incorporating an image attribute into the entity. That worked well, but I did have to read back on the Image Picker lesson from Chris at CodeWithChris to refamiliarise myself with what we briefly touched a couple of months ago with our RecipeApp.
The latest update to Core Data Mastery in SwiftUI is Mark’s massive chapter on Concurrency. Other than seeing the word on the occasional web post, I had absolutely no clue whatsoever what that was. I took the time to read Mark’s pages without trying to implement any of it in order to get an overview.
Now, I kind of see what it is and I get why it’s so important. As I understand it, it enables you to ensure that the right parts of your code are being run on the right “thread” because, if everything was to run on the one thread, the app would slow down to a crawl, hang, and freeze up on the end user. I’ve used a few apps like that, and now I wonder if the reason is because the developer hasn’t properly understood concurrency.
Concurrency isn’t something I’m going to dig deep into right now because it’s important to me to get the “guts” of my App in working order. I’m not taking time to make it “look nice” either, I just want “something” without getting the code bogged down with smoothing the sharp corners and burying the workings under colours and visuals.
It may be a couple of days before my next post but, I hope, by then, I’ll have figured out what I need to figuring in enhancing the Relationship to include a third entity.
Additonal Note:
Core Data Mastery in SwiftUI is bang up-to-date in that it works best with Xcode 14 and iOS 16. If using earlier versions, you may have to adapt some of the teachings to suit your environment. One that I came across was:
NavigationStack {
...
.sheet(...) { ...
...
.presentationDetents([.medium])
}
}
Both NavigationStack
and .presentationDetents()
are only available in Xcode 14 / iOS 16 – currently in beta. If your system is not updated to these versions, Xcode will throw up “Cannot find … in scope” type errors, so you won’t be able to run it. I would imagine that this also means that, if you wanted your app to support older versions of iOS, you’d need to find alternatives to this code.
Speaking of which, because I’m running the most up-to-date non-beta version of Xcode 13.4.1 which supports only up to the most recent iOS 15.5, opening the Xcode project that’s supplied with Core Data Mastery in Swift UI provides no simulators with which to test the code anyway.
On the plus side, however, it does mean that the book will be bang-up-to-date ready for when Xcode 14 / iOS 16 comes out of beta. As I’ve discovered for myself in the past, in this fast-changing world of coding, there’s nothing worse than learning outdated methods and code.