Utilizing SwiftData and a shared SQLite database in an app and its share extension. For those who merely faucet Share in Safari, and the extension is proven, if you activate the app, one view throws:
DraftsView : getDrafts(): Thread 1: Deadly error: ‘attempt!’ expression unexpectedly raised an error: Error Area=NSCocoaErrorDomain Code=256 “The file “default.retailer” couldn’t be opened.” UserInfo={NSFilePath=/non-public/var/cellular/Containers/Shared/AppGroup/455BCEA6-209A-41EA-852D-0488375BD111/Library/Software Help/default.retailer, NSSQLiteErrorDomain=1}
error: -executeRequest: encountered exception = I/O error for database at /non-public/var/cellular/Containers/Shared/AppGroup/455BCEA6-209A-41EA-852D-0488375BD111/Library/Software Help/default.retailer. SQLite error code:1, ‘no such desk: ZDRAFT’ with userInfo = {
NSFilePath = “/non-public/var/cellular/Containers/Shared/AppGroup/455BCEA6-209A-41EA-852D-0488375BD111/Library/Software Help/default.retailer”;
NSSQLiteErrorDomain = 1; }
None of that view’s objects are opened. As a result of the view saves the mannequin context, all these objects then seem completely deleted.
The unusual factor is the principle view is unaffected.
To keep away from concurrency points, there are not any @Question vars in both the app or the share extension, solely fetches as wanted.
SwiftData mannequin for the view which fails:
@Mannequin ultimate class ClassA {
@Attribute(.distinctive)
var id: String
@Relationship(deleteRule: .cascade, inverse: ClassB.mum or dad)
var issues: [ClassB] = [ClassB]()
}
@Mannequin ultimate class ClassB {
@Attribute(.distinctive)
var id: String
// Inverse hyperlink to mum or dad
var mum or dad: ClassA?
@Relationship(deleteRule: .cascade, inverse: ClassC.mum or dad)
var otherThings: [ClassC] = [ClassC]()
}
@Mannequin ultimate class ClassC {
@Attribute(.distinctive)
var id: String
// Inverse hyperlink to mum or dad
var mum or dad: ClassB?
}
For the view that is unaffected:
@Mannequin ultimate class Merchandise {
@Attribute(.distinctive)
var id: UUID
var itemUrl: String
}
Share extension is all one Swift class:
class ShareViewController: SLComposeServiceViewController {
non-public let modelContainer: ModelContainer
non-public let modelContext: ModelContext
required init?(coder: NSCoder) {
do {
modelContainer = attempt ModelContainer(for: SavedItem.self, configurations: ModelConfiguration(isStoredInMemoryOnly: false))
} catch {
fatalError("Didn't create the mannequin container: (error)")
}
modelContext = modelContainer.mainContext
tremendous.init(coder: coder)
}
[…]
func saveItem(itemUrl: String) {
var fetch = FetchDescriptor<Merchandise>(
predicate: #Predicate { merchandise in merchandise.itemUrl == itemUrl }
)
fetch.includePendingChanges = true
let dupes = attempt? modelContext.fetch(fetch)
guard dupes?.depend == 0 else { return }
let id = UUID()
let merchandise = Merchandise(id: id)
modelContext.insert(merchandise)
do {
attempt modelContext.save()
} catch(let error) {
print("error: (error.localizedDescription)")
}
}
}
Tried mannequin actors, was a crashy hairball.
For those who by no means view the share extension icon in Safari, app works advantageous.
Anybody have SwiftData share extension pattern code that works?