Meet SwiftData

RSS for tag

Discuss the WWDC23 Session Meet SwiftData

View Session

Posts under wwdc2023-10187 tag

28 Posts
Sort by:
Post not yet marked as solved
3 Replies
1.1k Views
Hello, I have just tried playing around with the new Swift Data framework and noticed something. Assume the following many-to-many relationship on two PersistentModels: @Model class Media { @Relationship(.nullify, inverse: \Tag.medias) var tags: [Tag] } @Model class Tag { var medias: [Media] } This compiles without problems. If we now make Media conform to Codable (or just Decodable), we get a compiler error: "Ambiguous use of 'getValue(for:)'". When expanding the @Model and the then revealed @PersistedProperty macro, we see that the error is in the getter of Tag.medias, where we call self.getValue(for: \.medias). It seems the compiler knows multiple overloads of this function, including: an overload that accepts a KeyPath with a PersistentModel value an overload that accepts a KeyPath with a Decodable value Since Media conforms to both protocols, the compiler understandably does not know which overload to use. So to my questions: Is this intended behavior? So are PersistentModels not supposed to be Decodable? If yes, what would be the preferred way (or a clean way) to decode a PersistentModel (e.g., from an API)? Best regards, Jonas
Posted
by
Post not yet marked as solved
1 Replies
760 Views
Hi, I could probably wait until tomorrow's deep dive session and just find out, but I'm curious to ask, are the SwiftData persistent containers still backed on SQLite primarily? I'm excited to replace Core Data in my existing SwiftUI app, but I've been dropping down to SQLite3 directly, for example, for using the FTS5 module for creating full-text-search tables alongside my Core Data tables to back more relevant results for .searchable UIs.
Posted
by
Post not yet marked as solved
3 Replies
1.5k Views
What is the best way to use swift data to store one off data models? For example an application state that you want to be persisted across application launches. The only examples I've seen use arrays of items which wouldn't work for having just one application state. Is it possible to query just one item?
Posted
by
Post not yet marked as solved
4 Replies
3.1k Views
Is SwiftData going to be immediately available to use with iOS 16? I ask because I'm working on an app which I'd like to release around the end of this month, and I'm about to implement CoreData for it, but wanted to see when SwiftData would be available. My guess was that SwiftData is for iOS 17 so I should just stick with CoreData for now and switch over later, but just wanted to check to make sure. Thanks!
Posted
by
Post not yet marked as solved
6 Replies
1.3k Views
I've been testing out SwiftData but haven't bee able to get ModelContext notifications working. I've tried both an objc observer and for await patterns but it never fires. If I listen for the older nsmanagedcontext notifications they are firing, but I am hoping that the new ones give an ID instead of an objectId. Has anyone got these working? Attempt 1: class NotificationObserver { init() { let didSaveNotification = ModelContext.didSave NotificationCenter.default.addObserver(self, selector: #selector(didSave(_:)), name: didSaveNotification, object: nil) } @objc func didSave(_ notification: Notification) { print(notification.name) } } Attempt 2: class NotificationObserver { init() { let didSaveNotification = ModelContext.didSave Task { for await note in NotificationCenter.default.notifications(named: didSaveNotification) { print(note) } } } }
Posted
by
Post marked as solved
1 Replies
1.4k Views
I just saw the available video according SwiftData and wanted to convert a project of mine. Both documentation and video mention this: By default, SwiftData includes all noncomputed properties of a class as long as they use compatible types. The framework supports primitive types such as Bool, Int, and String, as well as complex value types such as structures, enumerations, and other value types that conform to the Codable protocol. I tried to model an enum but I always get an error regarding the conformance to PersistentModel I made different type of enum all implementing RawRepresentable but I always get an error For example: enum Simple: Int16 { case one, two } @Model class Item { var simple: Simple = .one } I got those errors: No exact matches in call to instance method 'getValue' Candidate requires that 'Simple' conform to 'PersistentModel' (requirement specified as 'Value' : 'PersistentModel') Candidate requires that 'Simple' conform to 'Sequence' (requirement specified as 'Value' : 'Sequence') Did I miss something here?
Posted
by
Post not yet marked as solved
1 Replies
1.6k Views
Just for grins, I tried running the SwiftData generation tool on the existing Core Data model of a non-trivial app I've worked on for a decade or so. It's pretty substantial, and uses some more advanced features, so it seemed like an interesting test case. One of the warnings that was not reported by the UI, but which showed up in the generated code was quite a few instances of this: Entity inheritance on entity Bar (parent class Foo) is unsupported in SwiftData. Now that I'm looking at the code examples more carefully, I see an awful lot of final class, which maybe should have raised a red flag sooner. But to the best of my recollection, none of the sessions outright said that inheritance (was or) was not supported. Core Data has supported this functionality for a long time (maybe since the beginning). Assuming that this isn't supported in this first seed, are there plans to provide this functionality in the future? By the launch of iOS 17? (For the record, this model has 93 entities, of which 34 have parent entities. 14 are abstract, which I gather is also not supported. 3 of the entities are both abstract and have parent entities.)
Posted
by
610
Post marked as solved
4 Replies
3.4k Views
re: the SwiftData session "Create an app with SwifData" (https://developer.apple.com/videos/play/wwdc2023/10154) I corrected the @MainActor issue, but it seems to only work with the main ContentView and not other views. I get the following error for TripListItem for example : failed to find a currently active container for Trip
Posted
by
Post not yet marked as solved
4 Replies
2.7k Views
Hey, I am trying to save an enum in my model with SwiftData but getting a weird error message I do not understand at the moment, and I am pretty sure I am missing something here. public enum URLScheme: String, Codable { case https case http } @Model public class MyModel { public var urlScheme: URLScheme } When I try to save the model I get the following error message in the console: error: Row (pk = 1) for entity 'MyModel' is missing mandatory text data for property 'https' I was wondering if I need to tell SwiftData how to save my enum ? My assumption was that I can save any enum if it conforms to Codable. Am I doing something wrong here or is this a beta bug ? Thanks a lot for helping
Posted
by
Post not yet marked as solved
3 Replies
1.2k Views
I am trying to use SwiftData to perform a Query based on the name of the actor, which is inside a movie model. Here is the Movie model. @Model final class Movie { var title: String var year: Int @Relationship(.noAction, inverse: \Actor.movies) var actors: [Actor] = [] init(title: String, year: Int) { self.title = title self.year = year } } Here is my actual Query: _movies = Query(filter: #Predicate { $0.actors.contains(where: { $0.name.contains(actorName) }) }) But it returns nothing, even though I am passing actorName which exists in the movie.
Posted
by
Post not yet marked as solved
0 Replies
774 Views
I was wondering if ModelContext's fetch() contains an auto-updating results array? I ask because there is no documentation yet and in the WWDC23 lounge it was suggested by Debbie G to use fetch() to overcome the limitations of @Query i.e. no way to use dynamic filtering or sorting. I suppose we would call fetch() from onAppear and onChanged to support dynamic queries that also have auto-updating of results. Personally I don't understand why @Query and the old @FetchRequest were implemented as property wrappers instead of SwiftUI modifiers, e.g. .fetch(predicate:sort:) to match other modifiers like .task(id:). I was hoping for it to behave similar to Date's formatted() that returns a locale-aware string that automatically invalidates SwiftUI Text when the locale changes. Although I'm not exactly sure how it works. If fetch() doesn't auto-update then what would be the point of using it instead of just using NSFetchRequest with dictionary result type to get data into a SwiftUI view struct fast and memory efficient.
Posted
by
Post not yet marked as solved
3 Replies
1.2k Views
Using SwiftData, I have a model that uses an enum as a property and a custom Codable type import SwiftData import CoreLocation // MARK: - Main Model @Model class Cache { var size: CacheSize? var coordinates: CLLocationCoordinate2D } // MARK: - CacheSize Enum enum CacheSize: CaseIterable, Codable { case nano case micro case small case regular case large case veryLarge case notChosen case virtual case other } // MARK: - Codable for CLLocationCoordinate2D extension CLLocationCoordinate2D: Codable { enum CodingKeys: String, CodingKey { case lat, lng } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(self.latitude, forKey: .lat) try container.encode(self.longitude, forKey: .lng) } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let latitude = try container.decode(CLLocationDegrees.self, forKey: .lat) let longitude = try container.decode(CLLocationDegrees.self, forKey: .lng) self.init(latitude: latitude, longitude: longitude) } } When I fetch the object from the ModelContext and try to access the property corresponding to this enum, I have a fatal error raised in BackingData.swift: SwiftData/BackingData.swift:197: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(iGeo.CacheSize, Swift.DecodingError.Context(codingPath: [], debugDescription: "Invalid number of keys found, expected one.", underlyingError: nil)) When I try to read the CLLocationCoordinates2D property, I have also a crash in the Decodable init(from decoder: Decoder implementation when trying to read the first value from the container. Did I miss something here or did something wrong?
Posted
by
Post not yet marked as solved
0 Replies
847 Views
I'm stuck at an error EXC_BREAKPOINT (code=1, subcode=0x1a8d69a38)that is thrown in a class during initialization. The class is defined as: @Model public final class Parent { @Attribute(.unique) public var uuid: UUID /// The date specification. @Relationship(.cascade) public var dateSpec: DateSpec /// The title. public var title: Title /// The subtitle. public var subTitle: Subtitle public init(uuid: UUID, dateSpec: DateSpec, title: Title, subTitle: Subtitle) { self.uuid = uuid self.dateSpec = dateSpec self.title = title self.subTitle = subTitle } } The error is thrown in the var dateSpec property at the return self.getValue(for: \.dateSpec) call of the @PersistedProperty macro. DateSpec is defined this way: @Model public final class DateSpec { @Attribute(.unique) public var uuid: UUID /// The type of the date specification (`.point` or `.range`). public var type: DateSpecType @Relationship(.cascade) public var point: DatePoint @Relationship(.cascade) public var range: DateRange public init(uuid: UUID, type: DateSpecType = .none, point: DatePoint = .init(), range: DateRange = .init()) { self.uuid = uuid self.type = type self.point = point self.range = range } } And DatePoint is defined so: @Model public final class DatePoint { @Attribute(.unique) public var uuid: UUID public var format: String public var date: Date? public init(uuid: UUID, format: String, date: Date? = nil) { self.uuid = uuid self.format = format self.date = date } } (DateRange accordingly). So, as far as I understood the sessions, this should work. Or did I miss something? -- Edit: When taking out DatePoint and DateRange from the model, and replacing the properties by .transient wrappers that get/set the respective properties directly in DateSpec, then the error disappears. So, is the problem the cascading of the relationships between Parent and DateSpec, and DateSpec and DatePoint/DateRange?
Posted
by
Post not yet marked as solved
2 Replies
973 Views
I'm trying to instantiate my model and I'm getting an error on the set first property import Foundation import SwiftData @Model final class PointModel { var x: CGFloat var y: CGFloat init( x: CGFloat, y: CGFloat ) { self.x = x self.y = y } } extension PointModel { static var preview: PointModel { PointModel(x: 0, y: 0) } } let point = PointModel(x: location.x, y: location.y) { get { _$observationRegistrar.access(self, keyPath: \.x) return self.getValue(for: \.x) } set { _$observationRegistrar.withMutation(of: self, keyPath: \.x) { self.setValue(for: \.x, to: newValue) **Thread 1: Fatal error: Illegal attempt to use a nil as an Attribute - x + 151.0** } } } Has anyone else experienced this problem? Maybe someone knows how to solve this?
Posted
by
Post not yet marked as solved
0 Replies
646 Views
Hello everyone! I'm trying to run this project by Apple, but it doesn't let me, I'm trying to learn more about to swiftData... https://developer.apple.com/documentation/coredata/adopting_swiftdata_for_a_core_data_app On the code it says next: `@MainActor #Preview { AddBucketListItemView(trip: .preview) .modelContainer(PreviewSampleData.container) } But it show me next error, Type 'Trip' has no member 'preview' anybody knows how can I solved, thank you.
Posted
by
Post marked as solved
2 Replies
1.7k Views
When trying to delete the element from my list, I always got error in my model. get { _$observationRegistrar.access(self, keyPath: \.id) return self.getValue(for: \.id) <-- ERROR: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1a949aefc) } Because I am new in development, I don't know how to solve it.
Posted
by
Post marked as solved
3 Replies
1.3k Views
Not sure what I'm doing wrong here. I'm taking this opportunity to add persistence to an app that hadn't had it yet. I followed the session advice but I get this crash when running it: SwiftData/BackingData.swift:201: Fatal error: expected attribute to be Codable The crash is on this line: modelContext.insert(RentSplitDataModel()) The object being created and inserted there is simple and the compiler confirms it does conform to Codable: https://github.com/KyLeggiero/Rent-Split-for-iOS/blob/feature/MVP/Shared/Model/RentSplitDataModel.swift
Posted
by
Post not yet marked as solved
2 Replies
813 Views
I have a WidgetExtension using SwiftData (same ModelContainer setup used in the WatchApp: @main struct Watch_Widget: Widget { let kind: String = "Watch_Widget" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: Provider()) { entry in Watch_WidgetEntryView(entry: entry) .modelContainer(for: [Model1.self, Model2.self]) } .configurationDisplayName("App") .description("descriptions") } } Here's the same model used in the widget view: struct Watch_WidgetEntryView : View { @Query var models: [Model1] var body: some View { let gaugeVal = models.count Gauge(value: gaugeVal, in: 0...60) { Text("min") } currentValueLabel: { Text(String(Int(gaugeVal))) } .gaugeStyle(.accessoryCircular) .widgetLabel { Text("\(models.count) models") } .containerBackground(.fill.tertiary, for: .widget) } } When I build the WidgetExtension, the following error was thrown and the CK data isn't loaded properly: CloudKit setup failed because there is another instance of this persistent store actively syncing with CloudKit in this process.
Posted
by