iCloud & Data

RSS for tag

Learn how to integrate your app with iCloud and data frameworks for effective data storage

CloudKit Documentation

Post

Replies

Boosts

Views

Activity

CloudKit backed SwiftData @Relationship
Hi, does anyone know how to get @Relationship in SwiftData to cascade to the CloudKit container? I've managed to get SwiftData classes to show up in CloudKit but they are not related in line with the @Relationship as per the example project: @Relationship(.cascade) var bucketListItem: [BucketListItem] = []` They are simply separate records. As result the cascade of deletes doesn't work. Any ideas?
2
0
761
Jun ’23
How to subclass with SwiftData?
Hi, I want to subclass my model. Here is my superclass: import SwiftData @Model public class Control { @Attribute(.unique) public var frame: Frame init(frame: Frame) { self.frame = frame } } Here is my subclass: import SwiftData import CoreGraphics class SliderControl: Control { let axis: Axis var value: CGFloat = 0.0 init(axis: Axis, frame: Frame) { self.axis = axis super.init(frame: frame) } required public init(backingData: any BackingData<Control>, fromFetch: Bool = false) { // How to get `axis` and `value` from the backing data? } } I'm not sure how to use the backing data to re-create my object. My goal is to have multiple controls with unique properties.
5
4
2.7k
Jun ’23
Reading Codable properties raised a fatal error.
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?
3
1
1.3k
Jun ’23
@Model and Encodable cause the error Ambiguous use of 'setValue(for:to:)'
I test with a simple class and it can compile: @Model final class Book: Encodable { var name: String enum CodingKeys: CodingKey { case name } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) } } Then I try with the Trip class from sample and it cause an error: @Model final class Trip: Encodable { : enum CodingKeys: CodingKey { case name, destination, endDate, startDate, bucketList } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) try container.encode(destination, forKey: .destination) try container.encode(endDate, forKey: .endDate) try container.encode(startDate, forKey: .startDate) try container.encode(bucketList as! Set<BucketListItem>, forKey: .bucketList) } And I got the error Ambiguous use of 'setValue(for:to:)' I tried make BucketListItem and LivingAccommodation Encodable and still have error.
3
3
540
Jun ’23
Are enums with associated values supported by swiftdata in any real way?
I haven’t found any way to have a swift data model contain an enum with different associated values, each different types of models, in order to deal with models that require heterogenous collections. Is this simply not supported? Is it supported but not ever used with SwiftUI binding? Instead I’ve had to create my own sort of enum in the form of a model that contains optionals for every case but this is obviously not ideal.
2
2
994
Jun ’23
SwiftData won't work with Measurement types
I'm trying out SwiftData and converting my existing data models using Structs and Codable to Classes and SwiftData. I've got a model that has a Measurement<UnitMass> type. When I run the app after converting everything to use classes with the @Model macro, I get a fatal error: SwiftData/SchemaProperty.swift:325: Fatal error: Unexpected type for CompositeAttribute: NSUnitMass. Since Measurement conforms to Codable, and SwiftData should work with Codable types, why is this not working? I also tried marking the property with @Attribute(.transformable) and it didn't make a difference.
10
12
2.8k
Jun ’23
cannot open file
Running my app with SwiftData in iOS 17 beta on iPhone leads to error: cannot open file at line 46973 of [554764a6e7] os_unix.c:46973: (2) open(/private/var/mobile/Containers/Data/Application/ED4308D5-058B-41BC-A617-A46F9754E3EC/Library/Application Support/default.store) - No such file or directory API call with unopened database connection pointer misuse at line 179760 of [554764a6e7] It seems the database file has not been created yet, since it's the first time running the app with SwiftData.
5
1
925
Jun ’23
SwiftData #Predicate cannot test for nil relationship
In Xcode Version 15.0 beta (15A5160n) this predicate will not build: let thisPredicate = #Predicate<Ledgers> { ($0.myStore != nil) } The definition of .myStore in the Ledgers class is: var myStore: Stores? an optional relationship. Is there anyway to test for nil optional relationships in SwiftData? The inverse relationship in Stores is: @Relationship(.deny, inverse: \Ledgers.myStore) var myReceipts: [Ledgers]
10
2
1.8k
Jun ’23
SwiftData model in Swift package
Hi, I am looking for information on how to setup a ModelContainer for a Swift app when the SwiftData model is located in a Swift package. Let's say the model code resides in a package called DomainModel. That package was added target's embedded content and the model types are used to init the model container using the modelContainer(for:) view modifier on the ContentView of the app. This crashes the app on startup with a EXC_BAD_ACCESS code=2. When copying the model code from the package directly into the app, the app starts just fine. I kindly ask for a code sample or any information about how to setup the model container when using a model from a Swift package. Thanks in advance and I am looking forward to replacing CoreData 🙂
6
0
1.6k
Jun ’23
Do I need to add my own unique id?
Hi, if I have a @Model class there's always an id: PersistentIdentifier.ID underneath which, according to the current documentation "The value that uniquely identifies the associated model within the containing store.". So I am wondering if it is (good) enough to rely on this attribute to uniquely identify @Model class entities, or if there are edge cases where it does not work (like maybe when using CloudKit)? If anybody saw some information regarding this, please let me know :-) Cheers, Michael
4
3
1.3k
Jun ’23
Access Core Data ModelContainer with SwiftData
I have an app that uses CoreData and I want to migrate to SwiftData. After following the Migrate to SwiftData session, I only need to point to my old Core Data file to read the old data and convert it to the new SwiftData format. My question is how do I do this? Maybe worth mentioning is that my NSPersistentContainer(name: "Model") is different to my app name. Possible Solution? According to a Tweet by Donny Wals this is done this way: By default a SwiftData ModelContainer will create its underlying storage in a file called default.store. If you want to change this so you can use an existing Core Data SQLite file, you can point your container to that file instead: // point to your old sqlite file let url = URL.applicationSupportDirectory.appending(path: "Model.sqlite") let config = ModelConfiguration(url: url) modelContainer = try ModelContainer(for: [ Movie.self ], config) My Tested Code @main struct SwiftData_TestApp: App { let url = URL.applicationSupportDirectory.appending(path: "Model.sqlite") let config = ModelConfiguration(url: url) let modelContainer = try ModelContainer(for: [ Item.self ], config) var body: some Scene { WindowGroup { ContentView() } .modelContainer(modelContainer) } } The problem here is that I don’t get it to work in the main app struct. When using this the way described in Dive deeper into SwiftData (at 6:58) I only get the error: Cannot use instance member 'url' within property initializer; property initializers run before 'self' is available PS: There seems to be an issue with this WWDC session method anyway – see this post.
2
0
1.9k
Jun ’23
@Model issue in visionOS
It seems that @Model is not fully supported in visionOS. I've tried both an iPad app and a native visionOS app, and both crash when trying to use SwiftData. It's a minimal app from the template (no data) that I add a little data code to: import SwiftData @Model final class mapPin { var lat : Double var lon : Double init(lat: Double, lon: Double) { self.lat = lat self.lon = lon } } Building for visionOS produces: /var/folders/9p/ppkjrfhs393__cqm9z57k9mr0000gn/T/swift-generated-sources/@__swiftmacro_7Vision16mapPin5ModelfMm_.swift:2:13: error: declaration name '_$backingData' is not covered by macro 'Model' private var _$backingData: any SwiftData.BackingData<mapPin> = SwiftData.DefaultBackingData(for: mapPin.self) ^ /Users/arenberg/Developer/Beta/Vision1/Vision1/ContentView.swift:13:7: note: in expansion of macro 'Model' here final class mapPin { ^~~~~~~~~~~~~~ /var/folders/9p/ppkjrfhs393__cqm9z57k9mr0000gn/T/swift-generated-sources/@__swiftmacro_7Vision16mapPin5ModelfMc_.swift:1:1: error: type 'mapPin' does not conform to protocol 'PersistentModel' extension mapPin : SwiftData.PersistentModel {} ^ /Users/arenberg/Developer/Beta/Vision1/Vision1/ContentView.swift:13:7: note: in expansion of macro 'Model' here final class mapPin { ^~~~~~~~~~~~~~ /var/folders/9p/ppkjrfhs393__cqm9z57k9mr0000gn/T/swift-generated-sources/@__swiftmacro_7Vision16mapPin5ModelfMc_.swift:1:1: note: do you want to add protocol stubs? extension mapPin : SwiftData.PersistentModel {} ^ /Users/arenberg/Developer/Beta/Vision1/Vision1/ContentView.swift:13:7: note: in expansion of macro 'Model' here final class mapPin { ^~~~~~~~~~~~~~ /var/folders/9p/ppkjrfhs393__cqm9z57k9mr0000gn/T/swift-generated-sources/@__swiftmacro_7Vision16mapPin5ModelfMm_.swift:2:64: error: module 'SwiftData' has no member named 'DefaultBackingData' private var _$backingData: any SwiftData.BackingData<mapPin> = SwiftData.DefaultBackingData(for: mapPin.self) ^~~~~~~~~ ~~~~~~~~~~~~~~~~~~ /Users/arenberg/Developer/Beta/Vision1/Vision1/ContentView.swift:13:7: note: in expansion of macro 'Model' here final class mapPin { ^~~~~~~~~~~~~~```
8
2
1.5k
Jun ’23
Inserting a Model entity with a relationship results in a runtime error.
Hi, when inserting an entity with a relationship I get the following runtime error: Illegal attempt to establish a relationship 'group' between objects in different contexts [...]. The model looks like this: @Model class Person { var name: String @Relationship(.nullify, inverse: \Group.members) var group: Group init(name: String) { self.name = name } } @Model class Group { var name: String @Relationship(.cascade) public var members: [Person] init(name: String) { self.name = name } } It can be reproduced using this (contrived) bit of code: let group = Group(name: "Group A") ctx.insert(group) try! ctx.save() let descriptor = FetchDescriptor<Group>() let groups = try ctx.fetch(descriptor) XCTAssertFalse(groups.isEmpty) XCTAssertEqual(groups.count, 1) XCTAssertTrue(groups.first?.name == "Group A") let person = Person(name: "Willy") person.group = group ctx.insert(person) try ctx.save() (See also full test case below). Anybody experiencing similar issues? Bug or feature? Cheers, Michael Full test case: import SwiftData import SwiftUI import XCTest // MARK: - Person - @Model class Person { var name: String @Relationship(.nullify, inverse: \Group.members) var group: Group init(name: String) { self.name = name } } // MARK: - Group - @Model class Group { var name: String @Relationship(.cascade) public var members: [Person] init(name: String) { self.name = name } } // MARK: - SD_PrototypingTests - final class SD_PrototypingTests: XCTestCase { var container: ModelContainer! var ctx: ModelContext! override func setUpWithError() throws { let fullSchema = Schema([Person.self, Group.self,]) let dbCfg = ModelConfiguration(schema: fullSchema) container = try ModelContainer(for: fullSchema, dbCfg) ctx = ModelContext(container) _ = try ctx.delete(model: Group.self) _ = try ctx.delete(model: Person.self) } override func tearDownWithError() throws { guard let dbURL = container.configurations.first?.url else { XCTFail("Could not find db URL") return } do { try FileManager.default.removeItem(at: dbURL) } catch { XCTFail("Could not delete db: \(error)") } } func testRelAssignemnt_FB12363892() throws { let group = Group(name: "Group A") ctx.insert(group) try! ctx.save() let descriptor = FetchDescriptor<Group>() let groups = try ctx.fetch(descriptor) XCTAssertFalse(groups.isEmpty) XCTAssertEqual(groups.count, 1) XCTAssertTrue(groups.first?.name == "Group A") let person = Person(name: "Willy") person.group = group ctx.insert(person) try ctx.save() } }
4
3
1.9k
Jun ’23
Enable Permissions (iCloud)
Greetings! In my application I request permission from the user to utilize iCloud. func requestPermission() { CKContainer.default().requestApplicationPermission([.userDiscoverability]) { [weak self] returnedStatus, _ in DispatchQueue.main.async { if returnedStatus == .granted { self?.permissionStatus = true } } } } How can I programatically ask for this permission again via a button? Sometimes a user may deny or disable this permission in error. Thank you! :)
2
0
515
Jun ’23
Limits of CloudKit Public Database
Hello! I would like my users to save short videos (under 30seconds 1080p) to the public database for all other users to download and view. Is this possible? Will I run into any storage pricing with Apple if I were to pursue this as my application backend? I am looking at other methods as well (user sharing from their private database) so I can implement video sharing. Is this feasible and worth pursuing?
2
0
1k
Jun ’23
How to make SwiftData class Codable
Consider the Categories class below. Without the @Model line, Xcode has no problems. As soon as the @Model line is added, Xcode protests that the class does not conform to Decodable or Encodable. Apparently the @Model macro expanded macro prevents the implied boilerplate that the systems adds when the Codable protocol is added to the class. I've filed feedback (FB12444837) for this. Does anyone have suggestions that will let me avoid the boilerplate? This is the simplest class in my schema, I've got 12 other classes with many more variables. @Model class Categories: Identifiable, Codable { // MARK: Identifiable var id: UUID { return uuidKey } // MARK: - Properties @Attribute(.unique) var uuidKey: UUID = UUID() var dateCreated: Date = Date() var dateModified: Date = Date() var dateRealm: Date? = nil var uuidUser: UUID = UUID() var uuidFamily: UUID = UUID() var myName: String = "" }
5
7
2.1k
Jun ’23
Weird Coredata error
Hi I really don't understand. I have a record type on CloudKit where I store some data and a corresponding entity on core data that I sync with CloudKit with a very basic routine at some point I call this func: func GetUserFromCoredata(userID:String)->UserEntity? { var fetched:[UserEntity]?=nil let fetch = NSFetchRequest<UserEntity>(entityName:"UserEntity") let predicate = NSPredicate(format:"TRUEPREDICATE") fetch.predicate = predicate fetch.affectedStores = [DBGlobals.localStore, DBGlobals.cloudStore] do{ print("RICHIESTA FETCH UTENTI IN COREDATA") fetched = try context.fetch(fetch) } catch{ fatalError("errore nel recupero dell'elenco utenti") } if let found = fetched { for el in found { if el.userID == userID { return el } } } return nil } As you can see nothing special. it is only a fetch made on two stores. If I run the code 20 times 19 are good and 1 result in a fatal error with this text: 2023-06-28 17:56:49.684780+0200 xDeskApp[23313:2379150] -[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50 2023-06-28 17:56:49.712724+0200 xDeskApp[23313:2379150] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLFetchRequestContext: 0x283d88000> , -[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50 with userInfo of (null) 2023-06-28 17:56:49.974635+0200 xDeskApp[23313:2379150] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50' *** First throw call stack: (0x1bd4d4cb4 0x1b657c3d0 0x1bd649ab8 0x1bd4eb0e8 0x1bd551900 0x1c4c53594 0x1c4bdf848 0x1c4bdf4b0 0x1c4c81d80 0x1068fa038 0x10690b814 0x1c4c81c20 0x1c4bcef68 0x1c4bcee38 0x1c4bbe200 0x1c4bc9a78 0x1c4d3752c 0x1c4c02678 0x1c4bc86d8 0x1c4bbb9fc 0x1c4bb6b14 0x1c4cc97ec 0x104bf00b0 0x104bef860 0x104bee8f4 0x1c4f82ce8 0x1c4f82d8c 0x1c5068cac 0x1c4f1f3b0 0x1c4f11338 0x1c50689d4 0x1bd53dc04 0x1bd4ebcb4 0x1bd4eb6cc 0x1c4fcc800 0x10690b158 0x1068fa038 0x1069020b0 0x106902e28 0x10690fc74 0x21d250ddc 0x21d250b7c) libc++abi: terminating due to uncaught exception of type NSException (Recorded stack frame) ... and really, I can't understand. the predicate is absolutely basic, the entity exist, here I am not syncing anything, just fetching the records in the two stores... what am I doing wrong? why 19 su 20 are good and one is catching this error?
2
0
702
Jun ’23
SwiftData nested custom model CRASH
@Model class AModel { @Attribute(.unique) var id:String var date:Date var b:[BModel] init() { self.id = UUID().uuidString self.date = Date() self.b = [] } } @Model class BModel { @Attribute(.unique) var id:String var date:Date init() { self.id = UUID().uuidString self.date = Date() } } struct MainView: View { @Environment(\.modelContext) private var db @State private var a:AModel = AModel() var body: some View { VStack { } .onAppear { a.b.append(BModel()) print(a.b) } } } // CRASH : @Model class AModel { @Attribute(.unique) var id:String var date:Date var b:[BModel] /** Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) { get { _$observationRegistrar.access(self, keyPath: \.b) return self.getValue(for: \.b) } set { _$observationRegistrar.withMutation(of: self, keyPath: \.b) { self.setValue(for: \.b, to: newValue) } } } */ init() { self.id = UUID().uuidString self.date = Date() self.b = [] } } @Model class BModel { @Attribute(.unique) var id:String var date:Date init() { self.id = UUID().uuidString self.date = Date() } }
3
4
1.4k
Jun ’23
Thread 1: Fatal error: expected attribute to be Codable
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
7
1
1.5k
Jul ’23
Severe hangs with iOS 17 Beta 2 when using iCloud
I have my app including iCloud support in the App Store for many years now. When I run the app on iOS 17 Beta 2 I am experiencing a very bad performance because the main thread seems to be blocked most of the time. When I run the app using the Time Profiler in Instruments it also reports the hangs and the busy main thread. I looked into the profiler window to see methods with long runtime. The most prominent method was: [BRQuery itemCollectionGathererDidReceiveUpdates:deleteItemsWithIDs:] coming from "CloudDocs". That seems to be some iOS internal class. I do not really know where to look next and I want to know whether somebody of you also experienced a similar problem? Thanks, Dirk
0
0
707
Jul ’23