添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Hello all, I am struggling with a Predicate in SwiftData, not sure if that is not yet supported but maybe I am on the wrong path.. I have a class which contains an Array of Strings (Tags) which I want to search on, so I need to filter this array with a Predicate but I can't get it to work, any suggestions? Here is the code: Class @Model class Tasks { var taskTitle: String = "x" var taskDueDate: Date = Date.now var taskDetails: String = "x" var taskCompleted: Bool = false var taskTags: [String]? = [] var taskAddingDate: Date = Date.now init(taskTitle: String, taskAddedDate: Date, taskDetails: String, taskCompleted: Bool, taskTags:[String]? = nil, taskAddingDate: Date) { self.taskTitle = taskTitle self.taskDueDate = taskAddedDate self.taskDetails = taskDetails self.taskCompleted = taskCompleted self.taskTags = taskTags self.taskAddingDate = taskAddingDate Predicate I have so far (it is compiling and it runs without any problems but it is not returning anything) If I leave the searchString empty I get all the tasks, so filtering with the searchString is not woking. init(sortSelection: SortOptionTasks, addTask: Binding, completedTask: Binding, searchString: String, sortOrder: [SortDescriptor] = []) { self.sortSelection = sortSelection self._addTask = addTask self._completedTask = completedTask _task = Query(filter: #Predicate { task in if searchString.isEmpty { } else { task.taskTags!.contains { $0 == searchString } == true } , sort: sortOrder) I get this error even though everything is turned on, how can I solve it? It works on IOS but I get this error on VisionOS CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromPartialError:forStore:inMonitor:]_block_invoke(2726): : Found unknown error as part of a partial failure: let previewContainer:ModelContainer = { let config = ModelConfiguration(cloudKitDatabase: .private("iCloud.Multitools")) let container = try ModelContainer(for: NoteModel.self, configurations: config) return container catch { fatalError("Error to create container") My iOS Testflight App is crashing immediately after download/start (on all physical devices) iOS Console says: SwiftData/DataUtilities.swift:1093: Fatal error: Unable to parse keypath for non-PersistentModel Type The code is probably it is during self.modelContainer = try ModelContainer( for: Model1.self, Model2.self, Model3.self, Model4.self, configurations: ModelConfiguration(isStoredInMemoryOnly: isPreview)) modelContainer.mainContext.autosaveEnabled = true The app runs fine on physical devices in run scheme (debug or release) I have no clue how to solve this. Any ideas? I have the following predicate used in a SwiftData Query: #Predicate { searchText.isEmpty || $0.myarray.contains(where: { $0.text.localizedStandardContains(searchText) Even though this compiles, I get the unsupportedKeyPath error in the logs: Query encountered an error: SwiftData.SwiftDataError(_error: SwiftData.SwiftDataError._Error.unsupportedKeyPath) I thought I could use .contains(where:) inside predicates, but this doesn't work. What could be the problem? Item.myarray is an array of a Codable struct type, and searchText is a String. I want to make icloud backup using SwiftData in VisionOS and I need to use SwiftData first but I get the following error even though I do the following steps I followed the steps below I created a Model import Foundation import SwiftData @Model class NoteModel { @Attribute(.unique) var id: UUID var date:Date var title:String var text:String init(id: UUID = UUID(), date: Date, title: String, text: String) { self.id = id self.date = date self.title = title self.text = text I added modelContainer WindowGroup(content: { NoteView() .modelContainer(for: [NoteModel.self]) And I'm making inserts to test import SwiftUI import SwiftData struct NoteView: View { @Environment(\.modelContext) private var context var body: some View { Button(action: { // new Note let note = NoteModel(date: Date(), title: "New Note", text: "") context.insert(note) }, label: { Image(systemName: "note.text.badge.plus") .font(.system(size: 24)) .frame(width: 30, height: 30) .padding(12) .background( RoundedRectangle(cornerRadius: 50) .foregroundStyle(.black.opacity(0.2)) .buttonStyle(.plain) .hoverEffectDisabled(true) #Preview { NoteView().modelContainer(for: [NoteModel.self]) I have two models that are have a weird interaction: @Model public final class Position: Equatable, Identifiable { var zone: ZoneModel? @Relationship(deleteRule: .cascade, inverse: \Item.positions) var items = [Item]() var name: String = "" var weight: Int = 0 var weightAllowed: Int = 0 init(name: String, weightAllowed: Int) { self.name = name self.weightAllowed = weightAllowed @Model public final class Item: Equatable, Identifiable { var form: FormModel? var positions: [Position]() var count: Int = 0 var weight: Int = 0 init() {} There are many other tables that are all connected, but these are the ones where the problems arise. The PositionModel is able to properly store and persist the items: [ItemModel] variable, but the ItemModel runs into a problem after the app closes. I am getting this error in my SQL Stack Trace no such column: t1.Z_6POSITIONS in "SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ? " When looking at my sqlite database I see that the table name is not Z_5POSITIONS.Z_6POSITIONS, but it is Z_5POSITIONS.Z_7POSITIONS. Index T-SQL: CREATE INDEX "Z_5POSITIONS_Z_7POSITIONS_INDEX" ON "Z_5POSITIONS" ( "Z_7POSITIONS", "Z_5ITEMS" For extra context here is the SQL Stack Trace: CoreData: annotation: Connecting to sqlite database file at "/~/default.store" CoreData: sql: SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA' TraceSQL(0x110e76a60): SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA' CoreData: sql: pragma recursive_triggers=1 TraceSQL(0x110e76a60): pragma recursive_triggers=1 CoreData: sql: pragma journal_mode=wal TraceSQL(0x110e76a60): pragma journal_mode=wal CoreData: sql: SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ? no such column: t1.Z_6POSITIONS in "SELECT 0, t0.Z_PK FROM Z_5POSITIONS t1 JOIN ZPOSITION t0 ON t0.Z_PK = t1.Z_6POSITIONS WHERE t1.Z_5ITEMS = ? " CoreData: annotation: Disconnecting from sqlite database due to an error. I have on automatic save, and also just to be sure and test it I am manually saving the added on ItemModel object. Every other SwiftData object is being properly saved, including the Items to the Position side to the many-to-many relationship, but the inverse isn't working. Header(vm: vm, onSubmit: { if vm.selected == nil { vm.new.updateWeight(with: oc) report.form?.addItem(vm.new) try context.save() Logger.write("Save Successful.") } catch { Logger.write("Save error: \(error)") vm.new = ItemModel() } else { vm.selected = nil } .padding(.vertical, 10) I always get a successful save. But every time I close and reopen the app I run into the above issue. Does anyone have any insight into this or maybe can spot something I have wrong off a look? I am trying to create a variable of type Color inside the swift data model in Xcode playground . This gives me these errors : No exact matches in call to instance method 'setValue' No exact matches in call to instance method 'getValue' No exact matches in call to instance method 'setValue' What is the problem? My apps are set up to store data in a SQLite database on the device. The user is also able to add images and those are also stored on the device. The database and images are stored in the apps documents folder. The database is set up with four tables, one of them containing a list of selectable items so the information in that table is constant. The other three are read/write to the user. The database also contains a field, which contains true/false as to whether the app has been purchased or not. My thought behind was that this would make the users data private and secure. My apps are set up using UIKit so SwiftData is not an option unless I rewrite the entire app in SwiftUI. Or is there a good way to use SwiftData in UIKit? Is there a way to store/move this information into the cloud so that the data can be synced across multiple devices? Or maybe set up an import/export scenario using a CSV file for the database using Dropbox? Any help or advice would be appreciated. Thanks in advance. I have an app in the app store which is working fine. Some users reported that they have app crashing when they are using iOS 17.4 beta. I could recreate the issue and it is happening when ModelContainer is crerated. This code.. let configuration = ModelConfiguration(for: MyTodo.self, isStoredInMemoryOnly: false) modelContainer = try ModelContainer(for: MyTodo.self, configurations: configuration) } catch { fatalError("Failed to load model container.\(error)") is throwing this error message: Fatal error: Failed to load model container.SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer) Hi! I was trying to develop a todo list app. There are two models: import Foundation import SwiftData @Model class Item { var id: UUID var title: String var detail: String @Relationship(deleteRule: .cascade, inverse: \SubItem.item) var subitems: [SubItem] var isCompleted: Bool var timestamp: Date init(id: UUID = UUID(), title: String = "", detail: String = "", subitems: [SubItem] = [], isCompleted: Bool = false, timestamp: Date = .now) { self.id = id self.title = title self.detail = detail self.subitems = subitems self.isCompleted = isCompleted self.timestamp = timestamp @Model class SubItem { var id: UUID var title: String var isCompleted: Bool var item: Item init(id: UUID = UUID(), title: String = "", isCompleted: Bool = false, item: Item) { self.id = id self.title = title self.isCompleted = isCompleted self.item = item In a component view, I was trying to preload some sample data in the preview: struct ItemRowView: View { @Bindable var item: Item //...... #Preview { let schema = Schema([ Item.self, SubItem.self let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true) let container = try! ModelContainer(for: schema, configurations: [modelConfiguration]) let context = container.mainContext var item: Item = Item(title: "Item title 1", detail: "") var subitem1 = SubItem(title: "subitem 4", item: item) var subitem2 = SubItem(title: "subitem 2", item: item) context.insert(item) context.insert(subitem1) context.insert(subitem2) return ItemRowView(item: item) .modelContainer(container) .padding() However, item.subitems is always empty in this view. What's wrong? I'm trying to write a unit test for a SwiftData migration. In the teardown function I delete the SQLite container files, but then the underlying sqlite library complains. There must be a way to gracefully terminate the SwiftData container before I delete the files, but I don't see how. Simplying nil-ifying the references doesn't work. I don't see any obvious close functions, so I hope someone knows a non-obvious function. override func tearDownWithError() throws { // Cleanup resources // -- DOES NOT CLOSE UNDERLYING SQLITE ACCESS -- self.container = nil self.context = nil // Delete database try FileManager.default.removeItem(at: self.url) catch { // Ignore file not found, report everything else. let nserror = error as NSError if nserror.domain != "NSCocoaErrorDomain" && nserror.code == 4 { throw error try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-shm")) try? FileManager.default.removeItem(at: self.url.deletingPathExtension().appendingPathExtension("store-wal")) I get these errors for .store, store-shm, and .store-wal: BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: /Users/(ME)/Library/Developer/XCTestDevices/C52F4E12-EB4F-4639-9866-C3A7126155FA/data/Containers/Data/Application/B0EE90C6-B95D-4185-890D-6F20766B9B3B/tmp/test1.store invalidated open fd: 11 (0x11) If the worst comes to the worst, I'll work around it by using a differently-named container for each test, but as they're in tmp they'll get cleaned up for me eventually. if you have an array of object IDs, with CoreData you can fetch all of the objects for those IDs at once with the right predicate. It would look something like this: let objectIDs: [NSManagedObjectID] = [id1,id2,id3,id4] let predicate = NSPredicate(format: "self in %@", objectIDs) Can something similar be created with a SwiftData predicate? For now I fetch all ids one by one and as you might guess, performance wise this is not great. I have made the following code to basically play around with haptics: LibraryView.swift import SwiftUI import SwiftData struct LibraryView: View { @Environment(\.modelContext) var modelContext @Query/*(sort: \CustomHaptic.dateMade)*/ var customHapticArray: [CustomHaptic] @Query/*(sort: \DefaultHaptic.dateMade)*/ var defaultHapticArray: [DefaultHaptic] @State private var showingAddCustomHaptic = false @State private var showingAddDefaultHaptic = false var body: some View { NavigationStack { VStack { List { ForEach(customHapticArray) { customHaptic in HStack { VStack { Text("\(customHaptic.sharpness)") Text("") Text("\(customHaptic.intensity)") Spacer() VStack { Text("\(customHaptic.repeats)") .sheet(isPresented: $showingAddCustomHaptic, content: { NewCustomHaptic() .toolbar { Button("New Custom Haptic", systemImage: "plus") { showingAddCustomHaptic = true .navigationTitle("Haptikiser") And NewCustomHaptic.swift, which is a sheet to add a new class CustomHaptic: @Model class CustomHaptic: Identifiable { var id = UUID() var dateMade = Date.now var repeats: Int var sharpness: Float var intensity: Float init(repeats: Int, sharpness: Float, intensity: Float) { self.repeats = repeats self.sharpness = sharpness self.intensity = intensity import SwiftUI import SwiftData struct NewCustomHaptic: View { @Environment(\.dismiss) var dismiss @Environment(\.modelContext) var modelContext @Query(sort: \CustomHaptic.dateMade) var customHapticArray: [CustomHaptic] @State var sharpness: Float = 1 @State var intensity: Float = 1 @State var repeats: Int = 3 let array0to1: [Float] = [0.2, 0.4, 0.6, 0.8, 1.0] var body: some View { VStack { Form { Section("Sharpness") { Picker(selection: $sharpness, label: Label("Sharpness", systemImage: "bolt.horizontal")) { ForEach(array0to1, id: \.self) { i in Text("\(Int(i * 10))") .pickerStyle(.segmented) Section("Intensity") { Picker(selection: $intensity, label: Label("Intensity", systemImage: "42.circle")) { ForEach(array0to1, id: \.self) { i in Text("\(Int(i * 10))") .pickerStyle(.segmented) Section("Repeats") { Stepper(value: $repeats, in: 1...10) { Label("\(repeats)", systemImage: "repeat") Button("Done") { let newCustomHaptic = CustomHaptic(repeats: repeats, sharpness: sharpness, intensity: intensity) modelContext.insert(newCustomHaptic) dismiss() .buttonStyle(.borderedProminent) .font(.title) Spacer() every single time i run it, i get " Query encountered an error: Error Domain=NSCocoaErrorDomain Code=256 "The file “default.store” couldn’t be opened." " in the console. And when I press done on the sheet, i get the same error. Thank you for helping I can't figure this one out. I've been able to load image textures from a struct model but not a class Model for my modelEntity. This for example, works for me, this is what I have been using up to now, without SwiftData, using a struct to hold my model if let imageURL = model.imageURL { let picInBox2 = ModelEntity(mesh: .generateBox(size: simd_make_float3(0.6, 0.5, 0.075), cornerRadius: 0.01)) picInBox2.position = simd_make_float3(0, 0, -0.8) if let imageURL = model.imageURL { if let texture = try? TextureResource.load(contentsOf: imageURL) { var unlitMaterial = UnlitMaterial() var imageMaterial = UnlitMaterial() unlitMaterial.baseColor = MaterialColorParameter.texture(texture) picInBox2.model?.materials = [imageMaterial] However, when I try to use my SwiftData model it doesn't work. I need to convert Data to url and I am not able to do this. This is what I would like to use for my image texture, from my SwiftData model @Attribute(.externalStorage) var image: Data? If/when I try to do this, substitute if let imageURL = item.image { for the old if let imageURL = model.imageURL { if let imageURL = model.imageURL { if let texture = try? TextureResource.load(contentsOf: imageURL) { var unlitMaterial = UnlitMaterial() var imageMaterial = UnlitMaterial() unlitMaterial.baseColor = MaterialColorParameter.texture(texture) picInBox2.model?.materials = [imageMaterial] it doesn't work. I get the error: Cannot convert value of type 'Data' to expected argument type 'URL' How can i convert the type 'Data' to expected argument type 'URL'? The original imageURL I am using here comes from the struct Model where it's saved as a variable var imageURL: URL? = Bundle.main.url(forResource: "cat", withExtension: "png") I am at my wit's end. Thank you for any pointers! struct NyxApp: App { // TODO: handle exception let container = try! ModelContainer(for: Track.self, Artist.self) var body: some Scene { WindowGroup { ContentView() .modelContainer(container) // Function to add debug data let artist = Artist( // ... let track = Track( // ... artists: [artist], // ... context.insert(track) try! context.save() The Track entity stores the Artist in Track.artists temporarily, but when I restart the app, the array is empty. The Artist.tracks array won't even get populated after inserting the track. I didn't find much useful information about many-to-many relationships that would explain my issue. Any help is appreciated, thank you! Hi, for my Swift Student Challenge, I'd like to store persistent data. User would be able to "Mark as done" a task, which will then be stored. However I'm not a huge fan of CoreData, which is very complicated. SwiftData would be perfect, but it's only available in iOS 17, and playgrounds are iOS 16 and newer. I could also use an external library, such as Realm DB. I really would like to use SwiftData but it seems very compromised. I red that third-part libraries are not forbidden (https://forums.developer.apple.com/forums/thread/74533) so I could technically use Realm (https://realm.io/) Can anyone help me with this choice ? Thanks! I'm currently working on a data model migration in Swift using a custom schema migration plan. My project involves migrating settings from one schema version to another (SchemaV1 to SchemaV2). Both schema versions include a class named FSViz, but with slightly different properties. In the newer schema, SchemaV2, I introduced a new property named textSettings of type TextSetting, replacing the textColor property from SchemaV1. Here's a simplified version of my migration code and class definitions: Model: extension SchemaV1 { @Model public final class FSViz { @Attribute(.unique) public let id: UUID public var textColor: TextColor init(textColor: TextColor) { self.id = UUID() self.textColor = textColor extension SchemaV2 { @Model public final class FSViz { @Attribute(.unique) public let id: UUID public var textSettings: TextSetting init(textSettings: TextSetting) { self.id = UUID() self.textSettings = textSettings initMyApp: public struct InitMyApp { static func makeInitialFSViz() -> FSViz? { FSViz(textSettings: makeTextSettings()) public static func makeFSViz() -> FSViz { FSViz(textSettings: makeTextSettings()) static func makeTextSettings() -> TextSetting { TextSetting( textColor: TextColor(red: 1, green: 1, blue: 1, alpha: 1) MigrationPlan: enum MyAppMigrationPlan: SchemaMigrationPlan { static var schemas: [VersionedSchema.Type] { [SchemaV1.self, SchemaV2.self] static var stages: [MigrationStage] { [migrateV1toV2] static let migrateV1toV2 = MigrationStage.custom(fromVersion: SchemaV1.self, toVersion: SchemaV2.self, willMigrate: nil, didMigrate: { context in let fetchDescriptor = FetchDescriptor() let allV1Vizs = try context.fetch(fetchDescriptor) for v1Viz in allV1Vizs { let newTextSetting = SchemaV2.TextSetting(textColor: v1Viz.textColor) let newViz = SchemaV2.FSViz(textSettings: newTextSetting) print("migration processing") context.insert(newViz) try context.save() MyAppContainer: public typealias FSViz = SchemaV2.FSViz public typealias TextSetting = SchemaV2.TextSetting @MainActor public let MyAppContainer: ModelContainer = { let schema = Schema([]) let configuration = ModelConfiguration() let container = try ModelContainer(for: FSViz.self, migrationPlan: MyAppMigrationPlan.self) let context = container.mainContext if try context.fetch(FetchDescriptor()).isEmpty { if let fsViz = InitWaveBar.makeInitialFSViz() { container.mainContext.insert(fsViz) else { print("Error: makeInitialFSViz() returned nil") return container catch { fatalError(error.localizedDescription) However, when running the migration, I encounter the following error: Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={entity=FSViz, attribute=textSettings, reason=Validation error missing attribute values on mandatory destination relationship} This error suggests that there are missing attribute values on the mandatory textSettings relationship in the destination schema. I've double-checked my migration logic to ensure that textSettings is correctly initialized and assigned, but the error persists. Questions: How can I resolve the "missing attribute values on mandatory destination relationship" error during the migration? Is there a specific aspect of handling relationships during migrations in Swift that I'm overlooking? Any insights or suggestions on how to troubleshoot and resolve this migration issue would be greatly appreciated.
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Developer Forums Participation Agreement .
  • Forums
  • Terms of Use Privacy Policy License Agreements