Description:
I'm experiencing a critical issue with SwiftData custom migrations where objects created during migration appear to be inserted successfully but aren't persisted or found by queries after migration completes. The migration logs show objects being created, but subsequent queries return zero results.
Problem Details:
I'm migrating from schema version V2 to V3, which involves:
Renaming Person class to GroupData
Keeping the same data structure but changing the class name
Using a custom migration stage to copy data from old to new schema
Migration Code:
swift
static let migrationV2toV3 = MigrationStage.custom(
fromVersion: LinkMapV2.self,
toVersion: LinkMapV3.self,
willMigrate: { context in
do {
let persons = try context.fetch(FetchDescriptor<LinkMapV2.Person>())
print("Found (persons.count) Person objects to migrate") // ✅ Shows 11 objects
for person in persons {
let newGroup = LinkMapV3.GroupData(
id: person.id, // Same UUID
name: person.name,
// ... other properties
)
context.insert(newGroup)
print("Inserted GroupData: '\(newGroup.name)'") // ✅ Confirms insertion
}
try context.save() // ✅ No error thrown
print("Successfully migrated \(persons.count) objects") // ✅ Confirms save
} catch {
print("Migration error: \(error)")
}
},
didMigrate: { context in
do {
let groups = try context.fetch(FetchDescriptor<LinkMapV3.GroupData>())
print("Final GroupData count: \(groups.count)") // ❌ Shows 0 objects!
} catch {
print("Verification error: \(error)")
}
}
)
Console Output:
text
=== MIGRATION STARTED ===
Found 11 Person objects to migrate
Migrating Person: 'Riverside of pipewall' with ID: 7A08C633-4467-4F52-AF0B-579545BA88D0
Inserted new GroupData: 'Riverside of pipewall'
... (all 11 objects processed) ...
=== MIGRATION COMPLETED ===
Successfully migrated 11 Person objects to GroupData
=== MIGRATION VERIFICATION ===
New GroupData count: 0 // ❌ PROBLEM: No objects found!
What I've Tried:
Multiple context approaches:
Using the provided migration context
Creating a new background context with ModelContext(context.container)
Using context.performAndWait for thread safety
Different save strategies:
Calling try context.save() after insertions
Letting SwiftData handle saving automatically
Multiple save calls at different points
Verification methods:
Checking in didMigrate closure
Checking in app's ContentView after migration completes
Using both @Query and manual FetchDescriptor
Schema variations:
Direct V2→V3 migration
Intermediate V2.5 schema with both classes
Lightweight migration with @Attribute(originalName:)
Current Behavior:
Migration runs without errors
Objects appear to be inserted successfully
context.save() completes without throwing errors
But queries in didMigrate and post-migration return empty results
The objects seem to exist in a temporary state that doesn't persist
Expected Behavior:
Objects created during migration should be persisted and queryable
Post-migration queries should return the migrated objects
Data should be available in the main app after migration completes
Environment:
Xcode 16.0+
iOS 18.0+
SwiftData
Swift 6.0+
Key Questions:
Is there a specific way migration contexts should be handled for data to persist?
Are there known issues with object persistence in custom migrations?
Should we be using a different approach for class renaming migrations?
Is there a way to verify that objects are actually being written to the persistent store?
The migration appears to work perfectly until the verification step, where all created objects seem to vanish. Any guidance would be greatly appreciated!
Additional Context from my investigation:
I've noticed these warning messages during migration that might be relevant:
text
SwiftData.ModelContext: Unbinding from the main queue. This context was instantiated on the main queue but is being used off it.
error: Persistent History (76) has to be truncated due to the following entities being removed: (Person)
This suggests there might be threading or context lifecycle issues affecting persistence.
Let me know if you need any additional information about my setup or migration configuration!
iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm testing my app before releasing to testers, and my app (both macOS and iOS) is crashing when I perform one operation, but only in the production build.
I have data that loads from a remote source, and can be periodically updated. There is an option to delete all of that data from the iCloud data store, unless the user has modified a record. Each table has a flag to indicate that (userEdited). Here's the function that is crashing:
func deleteCommonData<T:PersistentModel & SDBuddyModel>(_ type: T.Type) throws {
try modelContext.delete(model: T.self, where: #Predicate<T> { !$0.userEdited })
}
Here's one of the calls that results in a crash:
try modelManager.deleteCommonData(Link.self)
Here's the error from iOS Console:
SwiftData/DataUtilities.swift:85: Fatal error: Couldn't find \Link.<computed 0x0000000104b9d208 (Bool)> on Link with fields [SwiftData.Schema.PropertyMetadata(name: "id", keypath: \Link.<computed 0x0000000104b09b44 (String)>, defaultValue: Optional("54EC6602-CA7C-4EC7-AC06-16E7F2E22DE7"), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "name", keypath: \Link.<computed 0x0000000104b09b84 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "url", keypath: \Link.<computed 0x0000000104b09bc4 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "desc", keypath: \Link.<computed 0x0000000104b09c04 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "userEdited", keypath: \Link.<computed 0x0000000104b09664 (Bool)>, defaultValue: Optional(false), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "modified", keypath: \Link.<computed 0x0000000104b09c44 (Date)>, defaultVal<…>
Here's a fragment of the crash log:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019373222c
Termination Reason: Namespace SIGNAL, Code 5, Trace/BPT trap: 5
Terminating Process: exc handler [80543]
Thread 0 Crashed:
0 libswiftCore.dylib 0x19373222c _assertionFailure(_:_:file:line:flags:) + 176
1 SwiftData 0x22a222160 0x22a1ad000 + 479584
2 SwiftData 0x22a2709c0 0x22a1ad000 + 801216
3 SwiftData 0x22a221b08 0x22a1ad000 + 477960
4 SwiftData 0x22a27b0ec 0x22a1ad000 + 844012
5 SwiftData 0x22a27b084 0x22a1ad000 + 843908
6 SwiftData 0x22a28182c 0x22a1ad000 + 870444
7 SwiftData 0x22a2809e8 0x22a1ad000 + 866792
8 SwiftData 0x22a285204 0x22a1ad000 + 885252
9 SwiftData 0x22a281c7c 0x22a1ad000 + 871548
10 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820
11 SwiftData 0x22a27cc48 0x22a1ad000 + 851016
12 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392
13 SwiftData 0x22a285b2c 0x22a1ad000 + 887596
14 SwiftData 0x22a285a10 0x22a1ad000 + 887312
15 SwiftData 0x22a285bcc 0x22a1ad000 + 887756
16 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820
17 SwiftData 0x22a27cc48 0x22a1ad000 + 851016
18 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392
19 SwiftData 0x22a27c0d8 0x22a1ad000 + 848088
20 SwiftData 0x22a27a654 0x22a1ad000 + 841300
21 SwiftData 0x22a1be548 0x22a1ad000 + 70984
22 SwiftData 0x22a1cfd64 0x22a1ad000 + 142692
23 SwiftData 0x22a1b9618 0x22a1ad000 + 50712
24 SwiftData 0x22a1d2e8c 0x22a1ad000 + 155276
25 CoreData 0x187fbb568 thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28
26 CoreData 0x187fc2300 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 24
27 CoreData 0x187fc19c4 closure #1 in closure #1 in NSManagedObjectContext._rethrowsHelper_performAndWait<A>(fn:execute:rescue:) + 192
28 CoreData 0x187fbbda8 thunk for @callee_guaranteed @Sendable () -> () + 28
29 CoreData 0x187fbbdd0 thunk for @escaping @callee_guaranteed @Sendable () -> () + 28
30 CoreData 0x187f663fc developerSubmittedBlockToNSManagedObjectContextPerform + 252
31 libdispatch.dylib 0x180336ac4 _dispatch_client_callout + 16
32 libdispatch.dylib 0x18032c940 _dispatch_lane_barrier_sync_invoke_and_complete + 56
33 CoreData 0x187fd7290 -[NSManagedObjectContext performBlockAndWait:] + 364
34 CoreData 0x187fc1fb8 NSManagedObjectContext.performAndWait<A>(_:) + 544
35 SwiftData 0x22a1b877c 0x22a1ad000 + 46972
36 SwiftData 0x22a1be2a8 0x22a1ad000 + 70312
37 SwiftData 0x22a1c0e34 0x22a1ad000 + 81460
38 SwiftData 0x22a23ea94 0x22a1ad000 + 596628
39 SwiftData 0x22a256828 0x22a1ad000 + 694312
40 Sourdough Buddy 0x104e5dc98 specialized ModelManager.deleteCommonData<A>(_:) + 144 (ModelManager.swift:128) [inlined]
41 Sourdough Buddy 0x104e5dc98 closure #1 in SettingsView.clearStarterData.getter + 876 (SettingsView.swift:243)
It works if I do the following instead:
try modelContext.delete(model: Link.self, where: #Predicate { !$0.userEdited })
Why would the func call work in development, but crash in production? And why does doing the more verbose way work instead?
I think this is a bug.
Thanks
i want to save data like images, text,amd mapviews with swiftui. It is only saved but if you delete the app of buy a new iPhone everything is deleted, how can I make if that the information saved on my app is saved even after I update the app, delete the app, or put the app in another iPhone with SwiftUI? i have watched youtube videos and im still confused,please help.
Hi everyone,
I'm looking for the correct architectural guidance for my SwiftData implementation.
In my Swift project, I have dedicated async functions for adding, editing, and deleting each of my four models. I created these functions specifically to run certain logic whenever these operations occur. Since these functions are asynchronous, I call them from the UI (e.g., from a button press) by wrapping them in a Task.
I've gone through three different approaches and am now stuck.
Approach 1: @MainActor Functions
Initially, my functions were marked with @MainActor and worked on the main ModelContext. This worked perfectly until I added support for App Intents and Widgets, which caused the app to crash with data race errors.
Approach 2: Passing ModelContext as a Parameter
To solve the crashes, I decided to have each function receive a ModelContext as a parameter. My SwiftUI views passed the main context (which they get from @Environment(\.modelContext)), while the App Intents and Widgets created and passed in their own private context. However, this approach still caused the app to crash sometimes due to data race errors, especially during actions triggered from the main UI.
Approach 3: Creating a New Context in Each Function
I moved to a third approach where each function creates its own ModelContext to work on. This has successfully stopped all crashes. However, now the UI actions don't always react or update. For example, when an object is added, deleted, or edited, the change isn't reflected in the UI. I suspect this is because the main context (driving the UI) hasn't been updated yet, or because the async function hasn't finished its work.
My Question
I'm not sure what to do or what the correct logic should be. How should I structure my data operations to support the main UI, Widgets, and App Intents without causing crashes or UI update failures?
Here is the relevant code using my third (and current) approach. I've shortened the helper functions for brevity.
// MARK: - SwiftData Operations
extension DatabaseManager {
/// Creates a new assignment and saves it to the database.
public func createAssignment(
name: String, deadline: Date, notes: AttributedString,
forCourseID courseID: UUID, /*...other params...*/
) async throws -> AssignmentModel {
do {
let context = ModelContext(container)
guard let course = findCourse(byID: courseID, in: context) else {
throw DatabaseManagerError.itemNotFound
}
let newAssignment = AssignmentModel(
name: name, deadline: deadline, notes: notes, course: course, /*...other properties...*/
)
context.insert(newAssignment)
try context.save()
// Schedule notifications and add to calendar
_ = try? await scheduleReminder(for: newAssignment)
newAssignment.calendarEventIDs = await CalendarManager.shared.addEventToCalendar(for: newAssignment)
try context.save()
await MainActor.run {
WidgetCenter.shared.reloadTimelines(ofKind: "AppWidget")
}
return newAssignment
} catch {
throw DatabaseManagerError.saveFailed
}
}
/// Finds a specific course by its ID in a given context.
public func findCourse(byID id: UUID, in context: ModelContext) -> CourseModel? {
let predicate = #Predicate<CourseModel> { $0.id == id }
let fetchDescriptor = FetchDescriptor<CourseModel>(predicate: predicate)
return try? context.fetch(fetchDescriptor).first
}
}
// MARK: - Helper Functions (Implementations omitted for brevity)
/// Schedules a local user notification for an event.
func scheduleReminder(for assignment: AssignmentModel) async throws -> String {
// ... Full implementation to create and schedule a UNNotificationRequest
return UUID().uuidString
}
/// Creates a new event in the user's selected calendars.
extension CalendarManager {
func addEventToCalendar(for assignment: AssignmentModel) async -> [String] {
// ... Full implementation to create and save an EKEvent
return [UUID().uuidString]
}
}
Thank you for your help.
The CloudKit Console includes a Unique Users table in the Usage section.
The numbers here are lower than what I would expect. Does this only track a certain percentage of users, e.g. users have opted in to share analytics with developers?
Hi,
Not sure how to describe my issue best: I am using SwiftData and CloudKit to store my data.
In the past, when I tested my app on different devices, the data would sync between the devices automatically. For whatever reason this has stopped now and the data no longer syncs. No matter what I do, it feels as if all the data is actually stored just locally on each device.
How can I check if the data is actually stored in the cloud and what could be reasons, why its no longer synching between my devices (and yes, I am logged in with the same Apple ID on all devices).
Thanks for any hint!
Max
When deleting a SwiftData entity, I sometimes encounter the following error in a document based SwiftUI app:
Fatal error: Unexpected backing data for snapshot creation: SwiftData._FullFutureBackingData<MyEntityClass>
The deletion happens in a SwiftUI View and the code used to retrieve the entity is standard (the ModelContext is injected from the @Environment):
let myEntity = modelContext.model(for: entityIdToDelete)
modelContext.delete(myEntity)
Unfortunately, I haven't yet managed to isolate this any further in order to come up with a reproducible PoC.
Could you give me further information about what this error means?
Hello,
From the documentation linked below, the limitations for Background Assets are the following:
Size Limit: 200 GB
Asset Pack Count: 100
I'm expecting I will need ~175 Asset Packs and around 500GB of storage.
I understand Background Assets is a new, but is there a process or a potential that these limits will be increased in the future? Or is there a way to request an increase?
I've tried contacting Apple Support as this is more of an Admin issue, however they've directed me here.
Case ID 102725356578
https://developer.apple.com/help/app-store-connect/reference/apple-hosted-asset-pack-size-limits
Thank you,
Tanner
I’m building an app that edits files in iCloud and uses an NSFilePresenter to monitor changes.
When a conflict occurs, the system calls presentedItemDidGain(_:).
In that method, I merge the versions by reading the current (canonical) version using NSFileVersion.currentVersionOfItem(at:) and the conflicting ones using NSFileVersion.unresolvedConflictVersionsOfItem(at:).
This generally works, but sometimes, if two devices edit the same file at the same time, each device sees its own local version as the current one. For example:
Device A writes fileVerA (slightly later in real time)
Device B writes fileVerB
On Device A all works fine, currentVersionOfItem returns fileVerA, as expected, and unresolvedConflictVersionsOfItem returns [fileVerB].
But on Device B, currentVersionOfItem returns fileVerB!? And unresolvedConflictVersionsOfItem returns the same, local file [fileVerB], without any hint of the other conflicting version, fileVerA.
Later, the newer version from the Device A arrives on Device B as a normal, non-conflicting update via presentedItemDidChange(_:).
This seems to contradict Apple’s documentation:
“The currentVersionOfItemAtURL: method returns an NSFileVersion object representing what’s referred to as the current file; the current file is chosen by iCloud on some basis as the current “conflict winner” and is the same across all devices.”
Is this expected behavior, or a bug in how iCloud reports file versions?
I'm running a project with these settings:
Default Actor Isolation: MainActor
Approachable Concurrency: Yes
Strict Concurrency Checking: Complete (this issue does not appear on the other two modes)
I receive a warning for this very simple use case. Can I actually fix anything about this or is this a case of Core Data not being entirely ready for this?
In reference to this, there was a workaround listed in the release notes of iOS 26 beta 5 (https://forums.swift.org/t/defaultisolation-mainactor-and-core-data-background-tasks/80569/22). Does this still apply as the only fix for this?
This is a simplified sample meant to run on a background context. The issue obviously goes away if this function would just run on the MainActor, then I can remove the perform block entirely.
class DataHandler {
func createItem() async {
let context = ...
await context.perform {
let newGame = Item(context: context)
/// Main actor-isolated property 'timestamp' can not be mutated from a Sendable closure
newGame.timestamp = Date.now
// ...
}
}
}
The complete use case would be more like this:
nonisolated
struct DataHandler {
@concurrent
func saveItem() async throws {
let context = await PersistenceController.shared.container.newBackgroundContext()
try await context.perform {
let newGame = Item(context: context)
newGame.timestamp = Date.now
try context.save()
}
}
}
Hello Apple Team,
We’re building a CloudKit-enabled Core Data app and would like clarification on the behavior and performance characteristics of Binary Data attributes with “Allows External Storage” enabled when used with NSPersistentCloudKitContainer.
Initially, we tried storing image files manually on disk and only saving the metadata (file URLs, dimensions, etc.) in Core Data. While this approach reduced the size of the Core Data store, it introduced instability after app updates and broke sync between devices. We would prefer to use the official Apple-recommended method and have Core Data manage image storage and CloudKit syncing natively.
Specifically, we’d appreciate guidance on the following:
When a Binary Data attribute is marked as “Allows External Storage”, large image files are stored as separate files on device rather than inline in the SQLite store.
How effective is this mechanism in keeping the Core Data store size small on device?
Are there any recommended size thresholds or known limits for how many externally stored blobs can safely be managed this way?
How are these externally stored files handled during CloudKit sync?
Does each externally stored Binary Data attribute get mirrored to CloudKit as a CKAsset?
Does external storage reduce the sync payload size or network usage, or is the full binary data still uploaded/downloaded as part of the CKAsset?
Are there any bandwidth implications for users syncing via their private CloudKit database, versus developer costs in the public CloudKit database?
Is there any difference in CloudKit or Core Data behavior when a Binary Data attribute is managed this way versus manually storing image URLs and handling the file separately on disk?
Our goal is to store user-generated images efficiently and safely sync them via CloudKit, without incurring excessive local database bloat or CloudKit network overhead.
Any detailed guidance or internal performance considerations would be greatly appreciated.
Thank you,
Paul Barry
Founder & Lead Developer — Boat Buddy / Vessel Buddy iOS App
Archipelago Environmental Solutions Inc.
Hello Apple Team,
We are looking at developing an iOS feature on our current development that stores user-generated images as CKAssets in the public CloudKit database, with access control enforced by our app’s own logic (not CloudKit Sharing as that has a limit of 100 shares per device). Each story or post is a public record, and users only see content based on buddy relationships handled within the app.
We’d like to confirm that this pattern is consistent with Apple’s best practices for social features. Specifically:
Is it acceptable to store user-uploaded CKAssets in the public CloudKit database, as long as access visibility is enforced by the app?
Are there any performance or quota limitations (e.g., storage, bandwidth, or user sync limits) that apply to CKAssets in the public database when used at scale?
Would CloudKit Sharing be recommended instead, even if we don’t require user-to-user sharing invitations?
For App Review, is this model (public CKAssets + app-enforced access control) compliant with Apple’s data and security expectations?
Are there any caching or bandwidth optimization guidelines for handling image-heavy public CKAsset data in CloudKit?
Thanks again for your time
Hi all,
As you know, when using SwiftData Cloudkit, all relationships are required to be optional.
In my app, which is a list app, I have a model class Project that contains an array of Subproject model objects. A Subproject also contains an array of another type of model class and this chain goes on and on.
In this type of pattern, it becomes really taxxing to handle the optionals the correct way, i.e. unwrap them as late as possible and display an error to the user if unable to.
It seems like most developers don't even bother, they just wrap the array in a computed property that returns an empty array if nil.
I'm just wondering what is the recommended way by Apple to handle these optionals. I'm not really familiar with how the CloudKit backend works, but if you have a simple list app that only saves to the users private iCloud, can I just handwave the optionals like so many do? Is it only big data apps that need to worry? Or should we always strive to handle them the correct way? If that's the case, why does it seem like most people skip over them? Be great if an Apple engineer could weigh in.
Every time I insert a subclass (MYShapeLayer) into the model context, the app crashes with an error:
DesignerPlayground crashed due to fatalError in BackingData.swift at line 908. Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb2dbc55f3f4c57f2 <x-coredata://B1E3206B-40DE-4185-BC65-4540B4705B40/MYShapeLayer/p1>))) with Optional(A6CA4F89-107F-4A66-BC49-DD7DAC689F77)
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var designs: [MYDesign]
var layers: [MYLayer] {
designs.first?.layers ?? []
}
var body: some View {
NavigationStack {
List {
ForEach(layers) { layer in
Text(layer.description)
}
}
.onAppear {
let design = MYDesign(title: "My Design")
modelContext.insert(design)
try? modelContext.save()
}
.toolbar {
Menu("Add", systemImage: "plus") {
Button(action: addTextLayer) {
Text("Add Text Layer")
}
Button(action: addShapeLayer) {
Text("Add Shape Layer")
}
}
}
}
}
private func addTextLayer() {
if let design = designs.first {
let newLayer = MYLayer(order: layers.count, kind: .text)
newLayer.design = design
modelContext.insert(newLayer)
try? modelContext.save()
}
}
private func addShapeLayer() {
if let design = designs.first {
let newLayer = MYShapeLayer(shapeName: "Ellipse", order: layers.count)
newLayer.design = design
modelContext.insert(newLayer)
try? modelContext.save()
}
}
}
#Preview {
ContentView()
.modelContainer(for: [MYDesign.self, MYLayer.self, MYShapeLayer.self], inMemory: true)
}
@Model
final class MYDesign {
var title: String = ""
@Relationship(deleteRule: .cascade, inverse: \MYLayer.design)
var layers: [MYLayer] = []
init(title: String = "") {
self.title = title
}
}
@available(iOS 26.0, macOS 26.0, *)
@Model
class MYLayer {
var design: MYDesign!
var order: Int = 0
var title: String = ""
init(order: Int = 0, title: String = "New Layer") {
self.order = order
self.title = title
}
}
@available(iOS 26.0, macOS 26.0, *)
@Model
class MYShapeLayer: MYLayer {
var shapeName: String = ""
init(shapeName: String, order: Int = 0) {
self.shapeName = shapeName
super.init(order: order)
}
}
Hi, thank you for your reply. I have checked and confirmed that all AppleUser entity fields (id, name, email, password, createdAt) are optional, relationships (posts, comments) are optional, and I assign values when creating a new object, but Core Data still throws a nilError during registration; I have uploaded my project to GitHub for your reference here: https://github.com/Kawiichao/job. If reviewing it requires any payment, please let me know in advance. Thank you very much for your kind offer—I really appreciate it!
Topic:
App & System Services
SubTopic:
iCloud & Data
I have a simple app that makes an HTTPS call to gather some JSON which I then parse and add to my SwiftData database. The app then uses a simple @Query in a view to get the data into a list.
on iOS 16 this works fine. No problems. But the same code on iOS 26 (targeting iOS 18.5) crashes after about 15 seconds of idle time after the list is populated. The error message is:
Could not cast value of type '__NSCFNumber' (0x1f31ee568) to 'NSString' (0x1f31ec718).
and occurs when trying to access ANY property of the list.
I have a stripped down version of the app that shows the crash available.
To replicate the issue:
open the project in Xcode 26
target any iOS 26 device or simulator
compile and run the project.
after the list is displayed, wait about 15 seconds and the app crashes.
It is also of note that if you try to run the app again, it will crash immediately, unless you delete the app from the device.
Any help on this would be appreciated.
Feedback number FB20295815 includes .zip file
Below is the basic code (without the data models)
The Best Seller List.Swift
import SwiftUI
import SwiftData
@main
struct Best_Seller_ListApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer (for: NYTOverviewResponse.self)
}
}
ContentView.Swift
import os.log
import SwiftUI
struct ContentView: View {
@Environment(\.modelContext) var modelContext
@State private var listEncodedName = String()
var body: some View {
NavigationStack () {
ListsView()
}
.task {
await getBestSellerLists()
}
}
func getBestSellerLists() async {
guard let url = URL(string: "https://api.nytimes.com/svc/books/v3/lists/overview.json?api-key=\(NYT_API_KEY)") else {
Logger.errorLog.error("Invalid URL")
return
}
do {
let decoder = JSONDecoder()
var decodedResponse = NYTOverviewResponse()
//decode the JSON
let (data, _) = try await URLSession.shared.data(from: url)
decoder.keyDecodingStrategy = .convertFromSnakeCase
decodedResponse = try decoder.decode(NYTOverviewResponse.self, from: data)
//remove any lists that don't have list_name_encoded. Fixes a bug in the data
decodedResponse.results!.lists = decodedResponse.results!.lists!.filter { $0.listNameEncoded != "" }
// sort the lists
decodedResponse.results!.lists!.sort { (lhs, rhs) -> Bool in
lhs.displayName < rhs.displayName
}
//delete any potential existing data
try modelContext.delete(model: NYTOverviewResponse.self)
//add the new data
modelContext.insert(decodedResponse)
} catch {
Logger.errorLog.error("\(error.localizedDescription)")
}
}
}
ListsView.Swift
import os.log
import SwiftData
import SwiftUI
@MainActor
struct ListsView: View {
//MARK: - Variables and Constants
@Query var nytOverviewResponses: [NYTOverviewResponse]
enum Updated: String {
case weekly = "WEEKLY"
case monthly = "MONTHLY"
}
//MARK: - Main View
var body: some View {
List {
if nytOverviewResponses.isEmpty {
ContentUnavailableView("No lists yet", systemImage: "list.bullet", description: Text("NYT Bestseller lists not downloaded yet"))
} else {
WeeklySection
MonthlySection
}
}
.navigationBarTitle("Bestseller Lists", displayMode: .large)
.listStyle(.grouped)
}
var WeeklySection: some View {
let rawLists = nytOverviewResponses.last?.results?.lists ?? []
// Build a value-typed array to avoid SwiftData faulting during sort
let weekly = rawLists
.filter { $0.updateFrequency == Updated.weekly.rawValue }
.map { (name: $0.displayName, encoded: $0.listNameEncoded, model: $0) }
.sorted { $0.name < $1.name }
return Section(header: Text("Weekly lists to be published on \(nytOverviewResponses.last?.results?.publishedDate ?? "-")")) {
ForEach(weekly, id: \.encoded) { item in
Text(item.name).font(Font.custom("Georgia", size: 17))
}
}
}
var MonthlySection: some View {
let rawLists = nytOverviewResponses.last?.results?.lists ?? []
// Build a value-typed array to avoid SwiftData faulting during sort
let monthly = rawLists
.filter { $0.updateFrequency == Updated.monthly.rawValue }
.map { (name: $0.displayName, encoded: $0.listNameEncoded, model: $0) }
.sorted { $0.name < $1.name }
return Section(header: Text("Monthly lists to be published on \(nytOverviewResponses.last?.results?.publishedDate ?? "-")")) {
ForEach(monthly, id: \.encoded) { item in
Text(item.name).font(Font.custom("Georgia", size: 17))
}
}
}
}
Hi everyone,
Complete newbie here. Building an app and trying to use Cloudkit. I've added the CloudKit capability, triple checked the entitlements file for appropriate keys, made sure the code signing entitlements are pointing to the correct entitlements file. I've removed and cleared all of those settings and even created a new container as well as refreshed the signing. I just can't seem to figure out why I keep getting this error:
Significant issue at CKContainer.m:747: In order to use CloudKit, your process must have a com.apple.developer.icloud-services entitlement. The value of this entitlement must be an array that includes the string "CloudKit" or "CloudKit-Anonymous".
Any guidance is greatly appreciated.
Hi,
I’m running into an issue with Core Data migrations using a custom NSMappingModel created entirely in Swift (not using .xcmappingmodel files).
Setup:
• I’m performing a migration with a manually constructed NSMappingModel
• One of the NSEntityMapping instances is configured as follows:
• mappingType = .customEntityMappingType (or .transformEntityMappingType)
• entityMigrationPolicyClassName is set to a valid subclass of NSEntityMigrationPolicy
• The class implements the expected methods like:
@objc func createDestinationInstances(…) throws { … }
@objc func createCustomDestinationInstance(…) throws -> NSManagedObject { … }
The policy class is instantiated (confirmed via logging in init()),
but none of the migration methods are ever called.
I have also tried adding valid NSPropertyMapping instances with real valueExpression bindings to force activation, but that didn’t make a difference.
Constraints:
• I cannot use .xcmappingmodel files in this context due to transformable attributes not compatible with the visual editor.
• Therefore, I need the entire mapping model to be defined in Swift.
Workaround:
As a temporary workaround, I’m migrating the data manually using two persistent stores and NSManagedObjectContext, but I’d prefer to rely on NSMigrationManager as designed.
Question:
Is there a known limitation that prevents Core Data from invoking NSMigrationPolicy methods when using in-memory NSMappingModel instances?
Or is there any specific setup required to trigger them when not loading from .xcmappingmodel?
Thanks in advance.
I'm working on a new app with SwiftData and now adding CloudKit Sync.
Everything is working fine in the simulator against the development CloudKit Schema. I successfully deployed the schema to production.
However, the TestFlight builds fail against production. This is what I see in the logs, but I haven't been able to find info on how to fix it.
Help appreciated.
CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2205): <private> - Never successfully initialized and cannot execute request '<private>' due to error: Error Domain=CKErrorDomain Code=2 "CKInternalErrorDomain: 1011" UserInfo={ContainerID=<private>, NSDebugDescription=CKInternalErrorDomain: 1011, CKPartialErrors=<private>, RequestUUID=<private>, NSLocalizedDescription=<private>, CKErrorDescription=<private>, NSUnderlyingError=0x1078e9fe0 {Error Domain=CKInternalErrorDomain Code=1011 UserInfo={CKErrorDescription=<private>, NSLocalizedDescription=<private>, CKPartialErrors=<private>}}}
CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1153): <private>: Successfully set up CloudKit integration for store (<private>): <private>
CoreData+CloudKit: -[NSCloudKitMirroringDelegate _enqueueRequest:]_block_invoke(1035): Failed to enqueue request: <private>
Error Domain=NSCocoaErrorDomain Code=134417 UserInfo={NSLocalizedFailureReason=<private>}
Hi all,
In my SwiftUI / SwiftData / Cloudkit app which is a series of lists, I have a model object called Project which contains an array of model objects called subprojects:
final class Project1
{
var name: String = ""
@Relationship(deleteRule: .cascade, inverse: \Subproject.project) var subprojects : [Subproject]?
init(name: String)
{
self.name = name
self.subprojects = []
}
}
The user will select a project from a list, which will generate a list of subprojects in another list, and if they select a subproject, it will generate a list categories and if the user selects a category it will generate another list of child objects owned by category and on and on.
This is the pattern in my app, I'm constantly passing arrays of model objects that are the children of other model objects throughout the program, and I need the user to be able to add and remove things from them.
My initial approach was to pass these arrays as bindings so that I'd be able to mutate them. This worked for the most part but there were two problems: it was a lot of custom binding code and when I had to unwrap these bindings using init?(_ base: Binding<Value?>), my program would crash if one of these arrays became nil (it's some weird quirk of that init that I don't understand at al).
As I'm still learning the framework, I had not realized that the @model macro had automatically made my model objects observable, so I decided to remove the bindings and simply pass the arrays by reference, and while it seems these references will carry the most up to date version of the array, you cannot mutate them unless you have access to the parent and mutate it like such:
project.subcategories?.removeAll { $0 == subcategory }
project.subcategories?.append(subcategory)
This is weirding me out because you can't unwrap subcategories before you try to mutate the array, it has to be done like above. In my code, I like to unwrap all optionals at the moment that I need the values stored in them and if not, I like to post an error to the user. Isn't that the point of optionals? So I don't understand why it's like this and ultimately am wondering if I'm using the correct design pattern for what I'm trying to accomplish or if I'm missing something? Any input would be much appreciated!
Also, I do have a small MRE project if the explanation above wasn't clear enough, but I was unable to paste in here (too long), attach the zip or paste a link to Google Drive. Open to sharing it if anyone can tell me the best way to do so. Thanks!