I've found a very strange behaviour which looks like a bug. SwiftUI sheet or fullScreenCover do not release objects that were passed to its item: parameter (and to the view builder body by the way, but here is the simplified case).
It works well and memory is releasing on iOS 16 built with both Xcode 14 or 15. (simulators, devices)
Memory is leaking and NOT releasing on iOS 17 built with Xcode 15. (simulator, device 17.0.2)
Any ideas how we can solve this or we have to wait for the bugfix? This is going to be a global memory leak, I am sure most of SwiftUI apps are using classes passed to the sheet or fullScreenCover.
struct SheetView: View {
@State var sheetVM: SheetVM?
var body: some View {
Button {
sheetVM = .init()
} label: {
Text("Navigate")
}
.sheet(item: $sheetVM) { sheetVM in
Color.yellow
}
}
}
final class SheetVM: ObservableObject, Identifiable {
@Published var title: String = "Title"
init() {
print("SheetVM init")
}
deinit {
print("... SheetVM deinit")
}
}
struct SheetView_Previews: PreviewProvider {
static var previews: some View {
SheetView()
}
}
Post
Replies
Boosts
Views
Activity
I have submitted the first version of my app with 2 In-Apps. It was rejected to make some updates. In-Apps was in status "Developer Action Needed". I've updated description and In-Apps are "Waiting for Review" now. But I cannot add them to the app anymore because they are not "Ready to Review".
How can I make them "Ready to Review" again, they are just not visible for attaching to the bundle?
I am trying to fill W-8BEN form on App Store Connect, but cannot understand what does “Title” field mean right above the main form on the same page. No explanations or examples there, can anybody explain please?
During developing I've created bundle ID for my app, setup CloudKit etc. and wanted to name my app let's say MyChatApp. I've created Bundle ID com.NameSurname.MyChatApp.
Then I've decided to name the app with better and unique name like LetsGoChat.
Do I need to change bundle ID to com.NameSurname.LetsGoChat or it does not matter? Personally for me I don't care if it will be different, but will it be something not correct for Apple when it will be time to review the app for AppStore?
I have sync troubles with CKServerChangeToken when re-accepting again CKShare. Here is the steps to explain, starting from the point when share accepted and everything synched.
Model:
List. It is parent for Items. It can be shared.
Item. Have parent List, sharing inherited from parent List.
Steps that are causing the problem:
Share accepted by user B, user A is owner, zone synched, CKServerChangeToken stored by User B.
User B's Shared Zone contains List1, List2 with some Items inside each
User B delete CKShare for List1 only from that zone in his Shared database, e.g. leaved share (shown as invited for User A now)
User B use the same link to accept share again, he is shown as accepted participant for User A, everything is fine so far.
User B perform sync operations, but turns out like nothing was changed since stored CKServerChangeToken and List1 with all it's items is being skipped on sync. CKFetchRecordZoneChangesOperation returns nothing as each of CKRecords (List1 and it's Items) was not changed. Updating List1 CKRecord solves the problem as it's a change after stored CKServerChangeToken. Also each Item CKRecord inside List1 must be updated to be detected by sync operation as updated records after CKServerChangeToken.
How to manage this issue?
Hello, Please look at the code below. When compiling, I am getting an error "Global function 'fetchingFunc(entityType:)' requires that 'NSManagedObject' conform to 'CloudKitManagedObject'". Somehow the row 22 works great, but row 27 doesn't work, though everything looks logically.
Row 27 will work if I will make fetchingFunc(entityType:) not generic receiving CloudKitManagedObject directly. But in that case NSFetchRequest<CloudKitManagedObject> at row 18 doesn't work.
For me not working row 27 looks like some sort of a bug, don't see any reason it should not work.
Actually the goal here is to make row 18 working, could not achieve that without making function generic.
import CloudKit
import CoreData
protocol CloudKitManagedObject where Self: NSManagedObject {
static var entityName: String { get }
}
extension CloudKitManagedObject where Self: NSManagedObject {
static func fetchRequest() -> NSFetchRequest<Self> {
return NSFetchRequest<Self>(entityName: self.entityName)
}
}
class Item: NSManagedObject, CloudKitManagedObject { static let entityName = "Item" }
class List: NSManagedObject, CloudKitManagedObject { static let entityName = "List" }
func fetchingFunc<SyncObj: CloudKitManagedObject>(entityType: SyncObj.Type) {
let fetchRequest: NSFetchRequest<SyncObj> = entityType.fetchRequest()
fetchRequest.predicate = nil
}
fetchingFunc(entityType: Item.self)
let types: [CloudKitManagedObject.Type] = [Item.self, List.self]
for type in types {
fetchingFunc(entityType: type) //This won't compile
}
Is there some way to effectively get final change for each changed NSManagedObject in Persistent History with it's final states?
Or maybe that's possible to get whole past context at timestamp and fetch it, so I can just compare it with the current one?
After fetching context returns an array of [NSPersistentHistoryTransaction], and it's not comfortable to navigate there as object can be updated many times (let's say 100 updates), and the only way to get final state is go through each update as transaction contains only updated property.
After single attempt to fetch context on persistentContainer right after internet was restored (NWPathMonitor update handler), CoreData+CloudKit mirroring stuck and messaging that no internet, and cannot initialise. All CloudKit requests work perfect, but CloudKitMirroring cannot do sync, only app restart helps.
Have no idea how simple fetch can kill CoreData mirroring... It happens each time I fetch on internet restore (I have to do that, to upload parent records to CloudKit manually as Apple did not implemented that in NSPersistentCloudKitContainer, all my records must have parents in order to share them).
2020-07-24 19:36:25.309059+0300 Grocery List[1045:148713] [error] error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate requestAbortedNotInitialized:]1379: <NSCloudKitMirroringDelegate: 0x281e048f0> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringDelegateSerializationRequest: 0x283c6cec0> B20F9DB7-9600-4456-B682-056F4849FE4D resultType: Records resultType: Records objectIDsToSerialize: {( 0xccdeb685a950d0db <x-coredata://D745D081-107C-46B4-BA82-FAF2D86D959C/Item/p100> )}' due to error: <CKError 0x282671440: "Network Unavailable" (3/NSURLErrorDomain:-1009); "Схоже, що немає інтернет-зʼєднання."> 2020-07-24 19:36:25.309837+0300 Grocery List[1045:148713] [error] error: CoreData+CloudKit: -[NSPersistentCloudKitContainer recordForManagedObjectID:]block_invoke(253): Record serialization failed with error: Error Domain=NSCocoaErrorDomain Code=134406 "Request 'B20F9DB7-9600-4456-B682-056F4849FE4D' was aborted because the mirroring delegate never successfully initialized due to error: <CKError 0x282671440: "Network Unavailable" (3/NSURLErrorDomain:-1009); "Схоже, що немає інтернет-зʼєднання.">" UserInfo={NSLocalizedFailureReason=Request 'B20F9DB7-9600-4456-B682-056F4849FE4D' was aborted because the mirroring delegate never successfully initialized due to error: <CKError 0x282671440: "Network Unavailable" (3/NSURLErrorDomain:-1009); "Схоже, що немає інтернет-зʼєднання.">}
Notifications on Simulator never fires, I just cannot test my app well. Specifically I've subscribed on CKDatabaseSubscription. Anyone knows how to allow notifications on Simulator?
I can receive notifications only on real device though, it works perfect there.
Hi, I am developing sharing feature with already working mirroring and need to set parentRecord to child items. I want to extend NSPersistentCloudKitContainer (or any it's component used for mirroring) in some way to get access to CKRecords it is creating before container will push records to the server.
Goal — I want to set CKRecord.parent right before CKModifyRecordsOperation fires somewhere in NSPersistentCloudKitContainer.
Reason — NSPersistentCloudKitContainer do not handle parent records by itself.
I've set up a Core Data mirroring to CloudKit using NSPersistentCloudKitContainer. My simplified data structure consists of List and Item. List have one-to-many relationship items with many Items, Item has parentList property.
When I am getting CKRecord associated with List NSManagedObject and sharing it, I expect all child Items to be shared too. I know, I can set parentRecord property for each CKRecord associated with the List
childRecord.setParent(parentRecord)
But I believe there is some smart way to avoid doing that manually, because everything is mirroring automatically and it looks not nice to start handling each single property manually to only set parentRecord.
Is there any way to do that for NSManagedObjects? Because my custom relationship does not mean for CloudKit that the List is parent for the Item.
Hi,
I am trying to fetch CKShare for NSManagedObject. Firstly I get CKRecord for it using NSPersistentCloudKitContainer's record(for:) method. And getting situation when:
First time record(for:) gives correct CKRecord
I successfully create CKShare, see it in online Dashboard
Next time record(for:) gives old CKRecord which don't have share yet, it's outdated!
I swipe down notification Notification Center or minimise the app (go to home screen), and when go back, database is being immediately updated and record(for:) returns correct CKRecord with existing share now.
I can get correct CKRecord if I use only recordID from CKRecord that I get from record(for:), and fetch updated CKRecord using fetch(withRecordID:completionHandler:).
But it increase awaiting time twice because I need to get response for correct CKRecord and then fetch CKShare for it. If no share for CKRecord, I could get that nil immediately but now I have to fetch correct updated CKRecord.
So, anyone know how to keep local database updated as expected without call Notification Center or minimising an app?
Hi,
I've set up NSPersistentCloudKitContainer with mirroring and it works well. I also managed how to create share for records. But how I can get shared record synced with my Core Data?
Example:
User A (owner) shared record with user B, how that record (with 1-to-many relationship) can be synchronised with user B Core Data?
How to change UICloudSharingController background color? When I try to affect controller's view, background color changes under the desired view with content (changes from .clear). Cannot find correct subview...