SwiftData

RSS for tag

SwiftData is an all-new framework for managing data within your apps. Models are described using regular Swift code, without the need for custom editors.

SwiftData Documentation

Posts under SwiftData tag

492 Posts
Sort by:
Post not yet marked as solved
0 Replies
48 Views
I have an Apple app that uses SwiftData and icloud to sync the App's data across users' devices. Everything is working well. However, I am facing the following issue: SwiftData does not support public sharing of the object graph with other users via iCloud. How can I overcome this limitation without stopping using SwiftData? Thanks in advance!
Posted
by olopul.
Last updated
.
Post marked as solved
3 Replies
461 Views
I'm using two loops, one nested in another to create and assign a subclass to the parent class. I'm using x for one loop and y for the other loop. Print statement shows the loop variables being updated correctly, however the subclass has both variables as the same value. I'm not sure if the value is being stored as the same value or being displayed as the same value. I've checked both creation and display code. I can't find the error. var body: some View { NavigationSplitView { List { ForEach(routes) { item in NavigationLink { Text("Route: \(item.route_name) \nSeason: \(item.route_season)\nCoordinates: \(item.route_coordinates)\nProcessed: \(String(item.route_processed))\nNumber of baseboards: \(item.route_baseboards.count)") } label: { Text(item.route_name) } //end route nav link } //end route for each .onDelete(perform: deleteItems) //end route nav ForEach(baseboards) { item in NavigationLink { //if let test = item.baseboard_heightPoints.count { Text("Grid Size: \(String(item.baseboard_grid_size))\nRow:\(String(item.baseboard_row))\nColumn:\(String(item.baseboard_column))\nHeight Point Count:")//\(String(item.baseboard_heightPoints.flatMap { $0 } .count))") //fix count later //Text("Test") // Text("test2") // } else { // Text("Grid Size: \(String(item.baseboard_grid_size))\nRow:\(String(item.baseboard_row))\nColumn:\(String(item.baseboard_column))\nHeight Point Count: 0") // } } label: { Text(String(item.baseboard_grid_size)) }} .onDelete(perform: deleteItemsBaseboards) //end baseboard route nav // ForEach(heightPoints) { item in NavigationLink { // Text("Row:\(String(item.hp_row))\nColumn:\(String(item.hp_column))\nElevation:\(String(item.hp_elevation))") // } label: { // Text("Row:\(String(item.hp_row))\nColumn:\(String(item.hp_column))") // }} //.onDelete(perform: deleteItemsBaseboards) } .toolbar { ToolbarItem { Button(action: addItem) { Label("Add Route", systemImage: "plus") } //Button(action: addItem) { //not showing up // Label("Add Baseboard", systemImage: "arrow.up") //} } } //end toolbar } detail: { Text("Select a route") } //end NavigationSplitView } //end view body private func addItem() { /*withAnimation { */ let newItem = Route( route_name: "test route " + UUID().uuidString, route_season: "summer", route_processed: false, route_coordinates: "Somewhere", route_region: "US", route_baseboards: []) modelContext.insert(newItem) //end add route //add baseboards to each route let bb_StartCol = 0 let bb_EndCol = 3 let bb_StartRow = 0 let bb_EndRow = 3 //let grid5m = 148 //let grid10m = 76 //let gridHD = 5760 var bb_grid_size = 5760 let bb_sectionsVerticle = 180 let bb_sectionsHorizonal = 360 var sectionData: Data var dataInputArray: [UInt8] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF8, 0xFF] sectionData = Data(withUnsafeBytes(of: dataInputArray, Array.init)) for x in bb_StartCol...bb_EndCol { //columns for y in bb_StartRow...bb_EndRow { //rows print(x,y) if bb_grid_size < 1000 { let newItem2 = Baseboard( baseboard_column: Int16(x), baseboard_row: Int16(y), texture: "Grid", baseboard_processed: false, baseboard_grid_size: Int16(bb_grid_size),//(x+2)+(y+2), baseboard_heightPoints: Array(repeating: Array(repeating: 0, count: bb_grid_size), count: bb_grid_size), baseboard_HPSection: [], baseboard_route: newItem //baseboard_hps: [] ) modelContext.insert(newItem2) //insert baseboard for each run } else { let newItem2 = Baseboard( baseboard_column: Int16(x), baseboard_row: Int16(y), texture: "Grid", baseboard_processed: false, baseboard_grid_size: Int16(bb_grid_size),//(x+2)+(y+2), baseboard_heightPoints: [], baseboard_HPSection: Array(repeating: Array(repeating: sectionData, count: bb_sectionsVerticle), count: bb_sectionsHorizonal), baseboard_route: newItem //baseboard_hps: [] ) modelContext.insert(newItem2) //insert baseboard for each run } //print(x,y) } //end y for loop - baseboards } //end x for loop - baseboards // } // end animation of adding new items } // end function add items private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(routes[index]) } } } private func deleteItemsBaseboards(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(baseboards[index]) } } } //private func deleteItemsHeightPoints(offsets: IndexSet) { // withAnimation { // for index in offsets { // modelContext.delete(heightPoints[index]) // } // } // } } #Preview { ContentView() .modelContainer(for: Route.self, inMemory: false) }
Posted
by CapFred.
Last updated
.
Post marked as solved
3 Replies
119 Views
I just purchased a new M3 chip MacBook Air a little after it came out. I was able to create and deploy an iOS application. However, now that I am trying to create a new project Xcode throws an error upon launch. Steps to recreate the error (if possible) Open Xcode Select create new app An error is where the preview should be. At this point I have added no code. It is all boiler plate from Apple.
Posted Last updated
.
Post not yet marked as solved
1 Replies
95 Views
Dear all, I have the following two classes: Stagioni: import SwiftData @Model class Stagione { @Attribute(.unique) var idStagione: String var categoriaStagione: String var miaSquadra: String @Relationship(deleteRule: .cascade) var rosa: [Rosa]? @Relationship(deleteRule: .cascade) var squadra: [Squadre]? @Relationship(deleteRule: .cascade) var partita: [CalendarioPartite]? init(idStagione: String, categoriaStagione: String, miaSquadra: String) { self.idStagione = idStagione self.categoriaStagione = categoriaStagione self.miaSquadra = miaSquadra } } CalendarioPartite: import SwiftData @Model class CalendarioPartite { var idGiornata: Int var dataPartita: Date var squadraCasa: String var squadraTrasferta: String var golCasa: Int var golTrasferta: Int var stagione: Stagione? init(idGiornata: Int, dataPartita: Date, squadraCasa: String, squadraTrasferta: String, golCasa: Int, golTrasferta: Int) { self.idGiornata = idGiornata self.dataPartita = dataPartita self.squadraCasa = squadraCasa self.squadraTrasferta = squadraTrasferta self.golCasa = golCasa self.golTrasferta = golTrasferta } } Now, I'd like to have a query which is showing in a view the list of partite depending on a selection of a specific Stagione. I've tried with the following query, but I'm getting the following error: "Instance member 'selectedStagione' cannot be used on type 'CalendarioCampionatoView'; did you mean to use a value of this type instead?" @Query(filter: #Predicate<CalendarioPartite> { $0.stagione == selectedStagione}) private var partite: [CalendarioPartite] = [] What I'm doing wrong? Thanks, A.
Posted
by AndreB82.
Last updated
.
Post not yet marked as solved
3 Replies
87 Views
If I annotate a class with @Observable I get this error in @Query: Expansion of macro 'Query()' produced an unexpected 'init' accessor If I remove @Observable the error goes away. Elsewhere I have .environment referencing the class. With @Observable this complains that the class needs to be @Observable. I am mystified. Does anyone have a suggestion?
Posted Last updated
.
Post not yet marked as solved
0 Replies
104 Views
I have spent hours trying to get @Query macros to compile. Mostly they throw up meaningless errors for example the following produces 3 compiler errors: @Query var stylesheets: [StyleSheet] Here's the expansion. The compiler complains that 'private' can't be used here, and it can't find _stylesheets. I searched everywhere to find a resolution then I came across the Query struct. I used it as follows to replace the @Query: let query = Query(FetchDescriptor<StyleSheet>(), animation: .smooth) let styleSheets = query.wrappedValue This also solves another issue that was bugging me - how to get the context when the environment variable is often rejected. All I need to do now is write: let context = query.modelContext None of the WWDC23 SwiftData videos mentions the use of the struct, which is a shame. It feels much like the CoreData approach to fetching data. I hope this helps some of you.
Posted Last updated
.
Post not yet marked as solved
0 Replies
94 Views
Dear all, I'm building an app leveraging SwiftData and I have the following two classes: Stagione: import SwiftData @Model class Stagione { @Attribute(.unique) var idStagione: String var categoriaStagione: String var miaSquadra: String @Relationship(deleteRule: .cascade) var rosa: [Rosa]? @Relationship(deleteRule: .cascade) var squadra: [Squadre]? @Relationship(deleteRule: .cascade) var partita: [CalendarioPartite]? init(idStagione: String, categoriaStagione: String, miaSquadra: String) { self.idStagione = idStagione self.categoriaStagione = categoriaStagione self.miaSquadra = miaSquadra } } Squadre: import SwiftData @Model class Squadre { var squadraCampionato: String var stagione: Stagione? init(squadraCampionato: String) { self.squadraCampionato = squadraCampionato } } Now, I have a view in which I'm calling a sheet to insert some Squadre: // Presenta il foglio per aggiungere una nuova partita GroupBox(label: Text("Dettagli Partita").font(.headline).padding()) { VStack { HStack { Text("Giornata:") TextField("Giornata", text: $idGiornata) .frame(width: 30) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } DatePicker("Data Partita:", selection: $dataPartita, displayedComponents: .date) .padding() HStack { Text("Squadra Casa:") .frame(width: 150) TextField("Squadra Casa", text: $squadraCasa) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() TextField("Gol Casa", text: $golCasa) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } HStack { Text("Squadra Trasferta:") .frame(width: 150) TextField("Squadra Trasferta", text: $squadraTrasferta) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() TextField("Gol Trasferta", text: $golTrasferta) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } HStack { Button("Salva") { if let partitaSelezionata = partitaSelezionata { // Se è stata selezionata una partita, aggiorna i suoi dati if let index = partite.firstIndex(where: { $0.id == partitaSelezionata.id }) { partite[index].idGiornata = Int(idGiornata) ?? 0 partite[index].dataPartita = dataPartita partite[index].squadraCasa = squadraCasa partite[index].golCasa = Int(golCasa) ?? 0 partite[index].squadraTrasferta = squadraTrasferta partite[index].golTrasferta = Int(golTrasferta) ?? 0 } } else { // Altrimenti, aggiungi una nuova partita aggiungiPartita(stagione: stagione) } // Chiudi il foglio di presentazione mostraAggiungiPartita = false // Resetta il campo di input idGiornata = "" dataPartita = Date() squadraCasa = "" golCasa = "" squadraTrasferta = "" golTrasferta = "" } .buttonStyle(.borderedProminent) .disabled(idGiornata.isEmpty || squadraCasa.isEmpty || squadraTrasferta.isEmpty || golCasa.isEmpty || golTrasferta.isEmpty) // Bottone Chiudi Button("Chiudi") { mostraAggiungiPartita = false } .buttonStyle(.borderedProminent) } } .padding() } } I'd like to insert a autocomplete function in the textfields "Squadra Casa" and "Squadra Trasferta", based on the list of Squadre contained in the class "Squadre" and filtered for a specific Stagione. Has anybody of you made something similar? Do you have any suggestions or code example which I can use? Thanks, A.
Posted
by AndreB82.
Last updated
.
Post marked as solved
4 Replies
490 Views
I am currently working on an app that uses the CLMonitor to check when the user has entered a specific region. When the user enters the region, a new region should be monitored, and the old region should be removed. Currently, I have a startMonitoring() method that contains the event handling logic: func startMonitoringConditions() { Task { monitor = await CLMonitor(MonitorNames.monitorName) if let identifiers = await monitor?.identifiers { if identifiers.count == 0 { if let coordinate = manager.location?.coordinate { await addNewRegionAtCoordinate(coordinate: coordinate) } } else { print("Previous Monitor Region is used.") } } for try await event in await monitor!.events { if let coordinate = manager.location?.coordinate { // do something... await monitor!.remove(event.identifier) await addNewRegionAtCoordinate(coordinate: coordinate) } } } } Unfortunately, adding a new region will not update the events collection in the CLMonitor, so the new region's events will not be handled in this method. Any help on how I could fix this problem would be greatly appreciated!
Posted
by selvi.
Last updated
.
Post not yet marked as solved
11 Replies
770 Views
Our app is using SwiftData + SwiftUI. After upgrading to Xcode 15.3 Beta, RC1, RC2, we’ve experienced the same issue that the app is having 100% CPU activity even when left idle. This happens as long as the SwiftUI is using @Query to fetch SwiftData and the query does return at least 1 result (there is no issue if the query returns empty result). We’ve tried the following and therefore confirmed that this is a Xcode 15.3 beta issue: Xcode 15.3 Beta + iOS 17.2 -> 100% CPU activity when idle Xcode 15.3 Beta + iOS 17.4 beta -> 100% CPU activity when idle Xcode 15.2 Beta + iOS 17.2 -> normal This only happens during debug run. When profiling / using instrument, this doesn't happen.
Posted
by fanwgwg.
Last updated
.
Post not yet marked as solved
1 Replies
91 Views
Has anyone successfully persisted Color, particularly in SwiftData? So far my attempts have failed: Making Color conform to Codable results in a run time error (from memory something about ColorBox). Color.Resolved already conforms Codable but this results in "SwiftData/ModelCoders.swift:124: Fatal error: Composite Coder only supports Keyed Container" None of the other color types conform to Codable (CGColor, NSColor and UIColor) so does the swift language really not have a persistable color type?
Posted
by Uasmel.
Last updated
.
Post not yet marked as solved
1 Replies
255 Views
@Query(filter: #Predicate<Note>{ note in note.isDeleted == false && (note.title != "" || note.content != "") } ,sort: [SortDescriptor(\Note.isPinned, order: .reverse),SortDescriptor(\Note.createdAt, order: .reverse)] , animation: .smooth(duration: 0.3) ) private var notes: [Note] if I delete filter part navigationLink works properly
Posted
by AzizK.
Last updated
.
Post not yet marked as solved
0 Replies
101 Views
I am new to swift. This is my Item.swift. import SwiftData @Model final class Item: Codable { var id: String var soundId: String var soundAppleId: String var soundType: String var type: String var authorId: String var text: String var createdAt: Date var actionsCount: Int var chainsCount: Int var rating: Int var loved: Bool var replay: Bool var heartedByUser: Bool @Relationship var author: Author? init(id: String, soundId: String, soundAppleId: String, soundType: String, type: String, authorId: String, text: String, createdAt: Date, actionsCount: Int, chainsCount: Int, ratings: Int, loved: Bool, replay: Bool, heartedByUser: Bool, author: Author) { self.id = id self.soundId = soundId self.soundAppleId = soundAppleId self.soundType = soundType self.type = type self.authorId = authorId self.text = text self.createdAt = createdAt self.actionsCount = actionsCount self.chainsCount = chainsCount self.rating = ratings self.loved = loved self.replay = replay self.heartedByUser = heartedByUser self.author = author } private enum CodingKeys: String, CodingKey { case id case soundId = "sound_id" case soundAppleId = "sound_apple_id" case soundType = "sound_type" case type case authorId = "author_id" case text case createdAt = "created_at" case actionsCount = "actions_count" case chainsCount = "chains_count" case rating case loved case replay case heartedByUser case author } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(String.self, forKey: .id) soundId = try container.decode(String.self, forKey: .soundId) soundAppleId = try container.decode(String.self, forKey: .soundAppleId) soundType = try container.decode(String.self, forKey: .soundType) type = try container.decode(String.self, forKey: .type) authorId = try container.decode(String.self, forKey: .authorId) text = try container.decode(String.self, forKey: .text) let dateString = try container.decode(String.self, forKey: .createdAt) let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" if let date = formatter.date(from: dateString) { createdAt = date } else { throw DecodingError.dataCorruptedError(forKey: .createdAt, in: container, debugDescription: "Date string does not match format expected by formatter.") } actionsCount = try container.decode(Int.self, forKey: .actionsCount) chainsCount = try container.decode(Int.self, forKey: .chainsCount) rating = try container.decode(Int.self, forKey: .rating) loved = try container.decode(Bool.self, forKey: .loved) replay = try container.decode(Bool.self, forKey: .replay) heartedByUser = try container.decode(Bool.self, forKey: .heartedByUser) author = try container.decode(Author.self, forKey: .author) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(soundId, forKey: .soundId) try container.encode(soundAppleId, forKey: .soundAppleId) try container.encode(soundType, forKey: .soundType) try container.encode(type, forKey: .type) try container.encode(authorId, forKey: .authorId) try container.encode(text, forKey: .text) let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" let dateString = formatter.string(from: createdAt) try container.encode(dateString, forKey: .createdAt) try container.encode(actionsCount, forKey: .actionsCount) try container.encode(chainsCount, forKey: .chainsCount) try container.encode(rating, forKey: .rating) try container.encode(loved, forKey: .loved) try container.encode(replay, forKey: .replay) try container.encode(heartedByUser, forKey: .heartedByUser) try container.encode(author, forKey: .author) } } @Model final class Author: Codable { var id: String var image: URL var username: String var bio: String? init(id: String, image: URL, username: String, bio: String?) { self.id = id self.image = image self.username = username self.bio = bio } private enum CodingKeys: String, CodingKey { case id case image case username case bio } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(String.self, forKey: .id) image = try container.decode(URL.self, forKey: .image) username = try container.decode(String.self, forKey: .username) bio = try container.decodeIfPresent(String.self, forKey: .bio) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(image, forKey: .image) try container.encode(username, forKey: .username) try container.encodeIfPresent(bio, forKey: .bio) } } In my ItemView when I try to access something inside author, Swift preview crashes. Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 SwiftData 0x1cb459e90 0x1cb3d3000 + 552592 1 SwiftData 0x1cb45ba7c 0x1cb3d3000 + 559740 2 SwiftData 0x1cb45e5f8 0x1cb3d3000 + 570872 3 SwiftData 0x1cb4190e4 0x1cb3d3000 + 286948 4 audition 0x100b436e0 Item.author.getter + 320 (@__swiftmacro_8audition4ItemC6author18_PersistedPropertyfMa_.swift:9) 5 ContentView.1.preview-thunk.dylib 0x105f23a20 closure #1 in closure #1 in closure #1 in closure #1 in ItemCard.__preview__body.getter + 820 (ContentView.swift:89) 6 SwiftUI 0x1cba41308 0x1cb47b000 + 6054664 7 ContentView.1.preview-thunk.dylib 0x105f22ee4 closure #1 in closure #1 in closure #1 in ItemCard.__preview__body.getter + 472 (ContentView.swift:84) 8 SwiftUI 0x1cc2e6c40 0x1cb47b000 + 15121472 9 ContentView.1.preview-thunk.dylib 0x105f228b8 closure #1 in closure #1 in ItemCard.__preview__body.getter + 388 (ContentView.swift:83) ...
Posted
by coratype.
Last updated
.
Post not yet marked as solved
0 Replies
95 Views
A few months back, I launched an app that operated solely on a local level. Recently, I've begun the process of integrating it with CloudKit, and so far, the model integration has been successful. I've utilized SwiftData for this task, making it relatively straightforward to adjust the models, as shown below: ` @Relationship(deleteRule: .cascade, inverse: \ItemForCategory.category) var itemForCategory : [ItemForCategory]? = [ItemForCategory]() ` In my initial version of the code, the widget functioned perfectly. However, I've encountered an error recently stating Missing return in instance method expected to return 'ItemForCategory?'. @MainActor private func getLastItem () -> ItemForCategory? { guard let modelContainer = try? ModelContainer(for: Category.self) else { return nil } let descriptor = FetchDescriptor<Category>() let appCategories = try? modelContainer.mainContext.fetch(descriptor) let lastItem = appCategories?.compactMap { $0.itemForCategory }.last return lastItem } The error surfaces at the return line of code. I'm hopeful that someone can assist me in resolving this issue. Thank you very much.
Posted Last updated
.
Post marked as solved
1 Replies
117 Views
I have a Category model that's defined like so: @Model final class Category { @Attribute(.unique) var id: UUID var name: String var parent_id: UUID? //categories can be children of other categories init(id: UUID, name: String, parent_id: UUID?) { self.id = id self.name = name self.parent_id = parent_id } } And I'm getting my categories from an API call and putting it into my View: import SwiftUI import SwiftData struct CategoryView: View { @Environment(\.modelContext) private var modelContext @Query private var categories: [Category] @Query(filter: #Predicate<Category>{ $0.parent_id == nil }) private var top_level_categories: [Category] var spacing: CGFloat = 25 var body: some View { HStack() { Text("Categories") .font(.title.bold()) Spacer() Text("see all") } .padding([.bottom, .top], 0) VStack(spacing: 20) { ScrollView(.horizontal) { HStack(spacing: spacing) { ForEach(top_level_categories) { category in Text(category.name!) } } } } .onAppear{ getCategories() } } func getCategories() { get_refresh_token { token in guard let token = token else { return } var urlRequest = URLRequest (url: URL(string:"https://api.test.com/categories")!) urlRequest.httpMethod = "GET" urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") urlRequest.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization") URLSession.shared .dataTask(with: urlRequest) { (data, response, error) in do { if let data = data { let c = try JSONDecoder().decode([Category].self, from: data) c.forEach { modelContext.insert($0) } try? modelContext.save() } } catch { print(error) } }.resume() } } } This runs fine the first time I run the app but when I run it again, I get the following error: ForEach<Array<Category>, UUID, Text>: the ID XXXXXX-XXXX-XXXX-XXXX-XXXXXX occurs multiple times within the collection, this will give undefined results! Not sure why this is happening since I thought putting the @Attribute(.unique) on ID means that the same category won't get added twice?
Posted Last updated
.
Post not yet marked as solved
0 Replies
106 Views
I am currently writing an app that is about writing stories. As of now, it is fairly simple: ContentView is your "Collection" of stories. PopupView is when you click on a button in ContentView. In popup view you enter the story title. Once you do that, you are brought to a blank page which is StoryView, where the NavigationTitle is what your story title is. Once I finish the story and leave the page / StoryView, it is still there, but once I close the app on my phone and reopen it, the story is gone and is not saved. I am a relatively new developer, so ive been relying on ChatGPT and Google Gemini for the saving parts of this, but it rarely works, and the furthest ive gotten with it is that it saves the story title but doesn't save the content of the story. I have a feeling that the AI is overdoing it as well. If anyone could help, please do so. Ive been trying to fix this for days. If you need me to provide any code, I am happy to do so. [Edited by Moderator]
Posted Last updated
.
Post not yet marked as solved
1 Replies
131 Views
I referred to the code provided in the article Adding and Editing Persistent Data in Your App in the SwiftData documentation and tested the "/PreviewHelper" approach. I found that if a model class contains a property of a struct, and that struct includes a Set property or an Array property, the Preview would throw an error. Here is an example of the model: @Model class Book { // ... var someStruct: SomeStruct // ... } struct SomeStruct: Codable { // ... var someCollection: Set<Int> // ... } In actuality, this model can run and store data without any issues, but it fails to run in the Preview. Is there a problem with the implementation of this Preview or is there any other reason? Are there better ways to perform Preview in SwiftData?
Posted
by LandFish.
Last updated
.
Post not yet marked as solved
1 Replies
148 Views
I know that this has been posted many times, but I am facing an issue where I can't save a model instance. I know that this is due to enums from others trying to find solutions. The error that shows: CoreData: error: Row (pk = 2) for entity 'ResidentInfo' is missing mandatory text data for property 'name' Solutions that I've tried: removed all enums from their respective structs to being standalone. making sure all enum calls use the full keyPath removing CustomStringConvertible from all enums and moving them to rawValue strings updating Xcode to 15.4b probably other things I've forgotten at this point File is too long to fit in post or comments (I'm sorry it's insanely long, it's a complex model), so I'll try to fit what I can where, are there anythings that stand out that may be an issue? Enums: enum Gender: String, CaseIterable, Codable { case male = "Male" case female = "Female" case transmale = "Trans Male" case transfemale = "Trans Female" case nonbinary = "Nonbinary" case other = "Other" } enum BodyBuild: String, CaseIterable, Codable { case small = "Small" case medium = "Medium" case large = "Large" } enum Status: String, Codable { case incomplete, complete } enum HairColor: String, CaseIterable, Codable { case black = "Black" case blonde = "Blonde" case dirtyBlonde = "Dirty Blonde" case brown = "Brown" case lightBrown = "Light Brown" case darkBrown = "Dark Brown" case red = "Red" } enum EyeColor: String, CaseIterable, Codable { case blue = "Blue" case brown = "Brown" case black = "Black" case green = "Green" case hazel = "Hazel" case gray = "Gray" case heterochromatic = "Heterochromatic" } enum RaceEthnicity: String, CaseIterable, Codable { case native = "American Indian or Alaska Native" case asian = "Asian" case black = "Black or African American" case pi = "Native Hawaiian or Other Pacific Islander" case white = "White" case mixed = "2 or More Races/Mixed" } enum MarkType: String, CaseIterable, Codable { case birthMark = "Birth Mark" case scar = "Scar" case tattoo = "Tattoo" case piercing = "Piercing" case other = "Other" } enum heightFormatStyle: String { case short, long, hash } enum suicideRiskLevel: String, Codable { case low = "Low" case medium = "Medium" case high = "High" } enum MedicationFrequency: String, CaseIterable, Codable { case daily = "Daily" case weekly = "Weekly" case biweekly = "Bi-Weekly" case monthly = "Monthly" case asNeeded = "As Needed" case temporary = "Temporary Use" case other = "Other" } enum SchoolOption: String, CaseIterable, Codable { case ged = "GED" case communityCollege = "Community College" case university = "4-Year College" } enum FamilyDiseaseTypes: String, CaseIterable, Codable { case alcoholism = "Alcoholism" case asthma = "Asthma" case cancer = "Cancer" case drugAbuse = "Drug Abuse" case hypertension = "High Blood Pressure" case nervousBreakdown = "Nervous Breakdown" case sca = "Sickle Cell Anemia" case seizures = "Convulsions, Seizures Epilepsy" case allergies = "Allergies" case birthDefect = "Birth Defect" case diabetes = "Diabetes" case heartDisease = "Heart Disease" case migraines = "Migraine Headaches" case obesity = "Obesity" case tuberculosis = "Tuberculosis" case thyroid = "Glandular/Thyroid Issues" } Structs: struct IdentifyingInformation: Codable { var hairColor: HairColor = HairColor.black var height: Height = Height(feet: 5, inches: 8) var race: RaceEthnicity = RaceEthnicity.native var build: BodyBuild = BodyBuild.small var eyeColor: EyeColor = EyeColor.blue var hispanic: Bool = false var distinguishingMarks: [DistinguishingMark] = [] var currentLivingSitutation: String = "" var currentSupportServices: String = "" struct DistinguishingMark: Codable, Identifiable { var id: UUID = UUID() var type: MarkType = MarkType.tattoo var location: String = "" var description: String = "" var photos: [Data] = [] } struct Height: Codable { var feet: Int var inches: Int func formatted(formatStyle: HeightFormatStyle = .short) -> String { switch formatStyle { case HeightFormatStyle.hash: return "\(feet)'\(inches)\"" case HeightFormatStyle.long: return "\(feet) feet \(inches) inches" case HeightFormatStyle.short: return "\(feet)ft \(inches)in" } } } } struct EmergencyNeeds: Codable { var food: Bool = false var shelter: Bool = false var clothing: Bool = false var hygeine: Bool = false var medical: Bool = false var mentalHealth: Bool = false var otherNeeds: String = "" var abuseNeglectAllegations: Bool = false var abuseReport: AbuseReport? = nil struct AbuseReport: Codable { var reportAccepted: Bool = false var whoAccepted: String = "" var reportNumber: String = "" } } struct RiskAssessment: Codable { var selfHarm: Bool = false var selfHarmAttempt: Bool = false var selfHarmExplanation: String? = nil var currentFeelings: String? = nil var dangerToOthers: Bool = false var dangerToOthersExplanation: String? = nil var suicideAssessmentRequired: Bool { return selfHarm || dangerToOthers } } struct SuicideAssessment: Loopable, Codable { var dateCompleted: Date = Date() var familyMember: Bool = false var treatedMentalIllness: Bool = false var chronicIllness: Bool = false var historyOfSelfDestructiveBehavior: Bool = false var recentLoss: Bool = false var isolatedAloneHopeless: Bool = false var goodbyeNoteOrPosessionDelegation: Bool = false var plan: Bool = false var betterOff: Bool = false var wishToDie: Bool = false var manualReview: Bool = false var comments: String = "" var helpCallMade: Bool = false var riskLevel: suicideRiskLevel { let riskScore = try? allProperties().reduce(0) { result, property in if let isTrue = property.value as? Bool, isTrue { return result + 1 } else { return result } } switch riskScore! { case 0 ... 3: return .low case 4 ... 7: return .medium default: return .high } } } [Continued in comments]
Posted Last updated
.
Post not yet marked as solved
0 Replies
118 Views
Hi, I'm new to Swift development and encountering an issue that I believe may be due to an error on my part. I have two questions regarding the following code: import AppIntents import SwiftUI import SwiftData @available(iOS 17.0, *) struct CopiarEventoIntent: AppIntent { @Environment(\.modelContext) private var context @Parameter(title: "Nome do Evento") var name: String @Parameter(title: "Data Inicial") var datai: Date @Parameter(title: "Data Final") var dataf: Date @Parameter(title: "Tipo de Evento") var tipo: String @Parameter(title: "Endereço") var endereco: String @Parameter(title: "Lembrete") var reminder: Bool static var title: LocalizedStringResource = "Adicionar Eventos" static var description = IntentDescription("Copiar Eventos e alterar datas", resultValueName: "Resultado") @MainActor func perform() async throws -> some IntentResult & ProvidesDialog { let calData = CalData(title: name, datei: datai, datef: dataf, tipo: tipo, endereco: endereco,reminder: reminder) context.insert(calData) return .result(dialog: "Evento copiado com sucesso!") } } @available(iOS 15.0, *) struct AppShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: CopiarEventoIntent(), phrases: [ "Copiar Evento" ], shortTitle: "Copiar Evento", systemImageName: "square.and.arrow.down" ) } } @available(iOS 15.0, *) struct ShortcutSelectionView: View { @Environment(\.modelContext) private var context @Query(sort: \CalData.title) private var caldatas: [CalData] @State private var selectedEvent: CalData? var body: some View { List(caldatas, id: \.self) { eventData in Button(action: { selectedEvent = eventData handleEventSelection() }) { Text(eventData.title) } } } private func handleEventSelection() { guard selectedEvent != nil else { return } } } When I run the shortcut, gives me the following error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot insert 'CalData' in this managed object context because it is not found in the associated managed object model. I attempted to save this using SwiftData with the following model: import SwiftData @Model class CalData { var title : String var datei : Date var datef : Date var tipo : String var endereco : String @Relationship(deleteRule: .cascade) var caldataval = [CalDataVal]() var reminder: Bool = false init(title:String, datei:Date, datef:Date, tipo:String, endereco:String, reminder:Bool){ self.title = title self.datei = datei self.datef = datef self.tipo = tipo self.endereco = endereco self.reminder = reminder } } As for the second question, how can I add a parameter that can have multiple values to save them to EventDataVal, resembling a one-to-many relationship: import SwiftData @Model class CalDataVal { var name : String var value : Double init(name:String, value:Double){ self.name = name self.value = value } } Thanks in advanced
Posted
by BAlves.
Last updated
.
Post not yet marked as solved
1 Replies
121 Views
Hi everyone, I'm trying to make use of a background actor in my SwiftUI project. Inserting data works with the ModelContainer's mainContext. Another context in a ModelActor, however, fails to write into the same database. I verify the results by opening the SQLite file on the file system. While the mainContext.insert call does indeed insert a row into the table, the ModelActor's context fails to do so. There is no error or message received in the ModelActor. The property autosaveEnabled is set to true. I wrote a sample project to reproduce the issue in isolation. It consists of a single source file that introduces the Model ToDo, the ToDoView, initializes the ModelContainer and ModelActor. Please find the source code below. Is there any mistake in my approach? import SwiftUI import SwiftData @Model final class ToDo { let title: String init(title: String) { self.title = title } } @main struct testSwiftDataApp: App { @State var modelContainer: ModelContainer @State var backgroundData: BackgroundDataActor init() { let modelContainer: ModelContainer = try! ModelContainer(for: ToDo.self) self.modelContainer = modelContainer self.backgroundData = BackgroundDataActor( modelContainer: modelContainer ) } var body: some Scene { WindowGroup { ToDoView(backgroundData: self.backgroundData) .modelContainer(modelContainer) } } } struct ToDoView: View { @Environment(\.modelContext) var modelContext @Query var todos: [ToDo] let backgroundData: BackgroundDataActor var modelContainer: ModelContainer { self.modelContext.container } var body: some View { VStack { Text("Add ToDo") TextField( "", text: .constant( "URL to database: " + "\(self.modelContainer.configurations.first!.url)" ) ) // This action will be invoked on the ModelActor's context Button { Task { let todo = ToDo(title: "Step 1") await self.backgroundData.store( id: todo.persistentModelID ) } } label: { Text("Create ToDo in background") } // This action will be invoked on the mainContext Button { Task { let todo = ToDo(title: "Step 2") self.modelContainer.mainContext.insert(todo) } } label: { Text("Create ToDo in foreground") } // Show the query results VStack { Text("Available ToDos") ForEach(self.todos) { Text($0.title) } } } } } @ModelActor actor BackgroundDataActor: ModelActor { func store(id: PersistentIdentifier) { print("Trying to save") print("Is auto save enabled: \(self.modelContext.autosaveEnabled)") if let dbo = self[id, as: ToDo.self] { self.modelContext.insert(dbo) try! self.modelContext.save() print("Saved into database") } } }
Posted
by anmarb.
Last updated
.
Post not yet marked as solved
0 Replies
179 Views
Hello, I have been working on SwiftData since a month now and i found very weird that every time i update a data inside a SwiftData model my app became very slow. I used the instrument if something was wrong, and i see memory increasing without releasing. My app have a list with check and unchecked elements (screeshot below). I just press check and unchecked 15 times and my memory start from 149mb to 361mb (screenshots below). For the code i have this model. final class Milestone: Identifiable { // ********************************************************************* // MARK: - Properties @Transient var id = UUID() @Attribute(.unique) var uuid: UUID var text: String var goalId: UUID var isFinish: Bool var createdAt: Date var updatedAt: Date var goal: Goal? init(from todoTaskResponse: TodoTaskResponse) { self.uuid = todoTaskResponse.id self.text = todoTaskResponse.text self.goalId = todoTaskResponse.goalId self.isFinish = todoTaskResponse.isFinish self.createdAt = todoTaskResponse.createdAt self.updatedAt = todoTaskResponse.updatedAt } init(uuid: UUID, text: String, goalId: UUID, isFinish: Bool, createdAt: Date, updatedAt: Date, goal: Goal? = nil) { self.uuid = uuid self.text = text self.goalId = goalId self.isFinish = isFinish self.createdAt = createdAt self.updatedAt = updatedAt self.goal = goal } } For the list i have var milestonesView: some View { ForEach(milestones) { milestone in MilestoneRowView(task: milestone) { milestone.isFinish.toggle() } .listRowBackground(Color.backgroundComponent) } .onDelete(perform: deleteMilestone) } And this is the cell struct MilestoneRowView: View { // ********************************************************************* // MARK: - Properties var task: Milestone var action: () -> Void init(task: Milestone, action: @escaping () -> Void) { self.task = task self.action = action } var body: some View { Button { action() } label: { HStack(alignment: .center, spacing: 8) { Image(systemName: task.isFinish ? "checkmark.circle.fill" : "circle") .font(.title2) .padding(3) .contentShape(.rect) .foregroundStyle(task.isFinish ? .gray : .primary) .contentTransition(.symbolEffect(.replace)) Text(task.text) .strikethrough(task.isFinish) .foregroundStyle(task.isFinish ? .gray : .primary) } .foregroundStyle(Color.backgroundComponent) } .animation(.snappy, value: task.isFinish) } } Does someone have a idea? Thanks
Posted
by agalpin.
Last updated
.