NSPersistentCloudkitContainer Memory Leak -> Crash? (iOS 15 beta 4, 5, 6 & 7...) - cloudkit

This is a copy of a thread I've created on Apple's Forum here
Background
I have an established app in the App Store which has been using NSPersistentCloudKitContainer since iOS 13 without any issues.
I've been running my app normally on an iOS device running the iOS 15 betas, mainly to see problems arise before my users see them.
Ever since iOS 15 beta 4 my app has failed to sync changes - no matter how small the change. An upload 'starts' but never completes. After a minute or so the app quits to the Home Screen and no useful information can be gleaned from crash reports. Until now I've had no idea what's going on.
Possible Bug in the API?
I've managed to replicate this behaviour on the simulator and on another device when building my app with Xcode 13 (beta 5) on iOS 15 (beta 5).
It appears that NSPersistentCloudKitContainer has a memory leak and keeps ramping up the RAM consumption (and CPU at 100%) until the operating system kills the app. No code of mine is running.
I'm not really an expert on these things and I tried to use Instruments to see if that would show me anything. It appears to be related to NSCloudkitMirroringDelegate getting 'stuck' somehow but I have no idea what to do with this information.
My Core Data database is not tiny, but not massive by any means and NSPersistentCloudKitContainer has had no problems syncing to iCloud prior to iOS 15 (beta 4).
If I restore my App Data (from an external backup file - 700MB with lots of many-many, many-one relationships, ckAssets, etc.) the data all gets added to Core Data without an issue at all. The console log (see below) then shows that a sync is created, scheduled & then started... but no data is uploaded.
At this point the memory consumption starts and all I see is 'backgroundTask' warnings appear (only related to CloudKit) with no code of mine running.
CoreData: CloudKit: CoreData+CloudKit: -[PFCloudKitExporter analyzeHistoryInStore:withManagedObjectContext:error:](501): <PFCloudKitExporter: 0x600000301450>: Exporting changes since (0): <NSPersistentHistoryToken - {
"4B90A437-3D96-4AC9-A27A-E0F633CE5D9D" = 906;
}>
CoreData: CloudKit: CoreData+CloudKit: -[PFCloudKitExportContext processAnalyzedHistoryInStore:inManagedObjectContext:error:]_block_invoke_3(251): Finished processing analyzed history with 29501 metadata objects to create, 0 deleted rows without metadata.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _scheduleAutomatedExportWithLabel:activity:completionHandler:](2800): <NSCloudKitMirroringDelegate: 0x6000015515c0> - Beginning automated export - ExportActivity:
<CKSchedulerActivity: 0x60000032c500; containerID=<CKContainerID: 0x600002ed3240; containerIdentifier=iCloud.com.nitramluap.Somnus, containerEnvironment="Sandbox">, identifier=com.apple.coredata.cloudkit.activity.export.4B90A437-3D96-4AC9-A27A-E0F633CE5D9D, priority=2, xpcActivityCriteriaOverrides={ Priority=Utility }>
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate executeMirroringRequest:error:](765): <NSCloudKitMirroringDelegate: 0x6000015515c0>: Asked to execute request: <NSCloudKitMirroringExportRequest: 0x600002ed2a30> CBE1852D-7793-46B6-8314-A681D2038B38
2021-08-13 08:41:01.518422+1000 Somnus[11058:671570] [BackgroundTask] Background Task 68 ("CoreData: CloudKit Export"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
2021-08-13 08:41:03.519455+1000 Somnus[11058:671570] [BackgroundTask] Background Task 154 ("CoreData: CloudKit Scheduling"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
Just wondering if anyone else is having a similar issue? It never had a problem syncing an initial database restore prior to iOS 15 (beta 4) and the problems started right after installing iOS 15 (beta 4).
I've submitted this to Apple Feedback and am awaiting a response (FB9412346). If this is unfixable I'm in real trouble (and my users are going to be livid).
Thanks in advance!
EDIT: It appears to be resolved from iOS 15.2 (beta 2) but the official word form Apple is that it is ‘unresolved’. I suspect this is because it’s still in testing and it may well be marked as resolved when 15.2 is made public

Related

Widget constantly reloads on device screen

I am using widget with CoreData and iCloud. They share the same App Group container. Everything works fine for a little, but spontaneously widget starts constantly reload and block itself on the device screen and in Widget Dashboard (place where you can search and add any widget).
It happens on iPhone Simulator (I use iPhone 8) and on a physical device as well. On device it behaves better, e.g., it can reload for a while and then stop.
My thoughts that it is connected to NSPersistentContainer but I'm not sure. I've tried these with no luck:
lazily load everything that goes with Core Data: CoreDataStack, PersistentContainer, etc.
use container.performBackgroundTask() to return data in getTimeline(in:completion:) faster. I have tested with only 1 record, results are the same.
remove everything with Core Data and put example code to show static text - that works, reloads disappear, but I need to show real data
In deferent scenarios I see these log messages:
1) -[EXSwiftUI_Subsystem beginUsing:withBundle:] unexpectedly called multiple times
2) Bogus event received by listener connection
3) [lifecycle] WARNING: Did not receive handshake message from the host after waiting ~2 seconds. THIS MAY BE A SPURIOUS LAUNCH OF THE PLUGIN due to a message to an XPC endpoint other than the main service endpoint, or the CPU is highly contended and this extension or its host is not getting enough CPU time.
and sometimes crashes with
1) signal SIGTERM
2) [NSConcreteFileHandle fileDescriptor]: unknown error
I can't figure out why it happens. I confused because it sometimes works and show my Core Data records, and reloads timeline correctly, but sometimes it goes crazy.
Any help or guidance will be appreciated.
Xcode 12.0.1 (12A7300)
Device: iPhone Xs, iOS 14.0.1

App Crashes But No TestFlight Crash Report

I have one user (with an iPhone 5) reporting that my app crashes on launch about 15 seconds after the screen goes black (the splash screen is black). The user downloaded a TestFlight build where I included checkpoints in the App delegate, but I don't get evidence that those checkpoints are crossed, and I never get a crash report.
I changed the entry point on the storyboard to a blank view controller, and now I can see that the checkpoints are being crossed. It's occurred to me that Watchdog is suspending the app due to storyboard resources taking too long to load, but all the images are built in real-time as needed, with the exception of four tiny tab-bar icons. There are several audio files but they are loaded on demand. I can't think of any other resources that could be causing a delay. No one else has reported this problem, and I'm stumped.
Any insight appreciated, especially as to why I'm not seeing a crash report or checkpoints from TestFlight.
Your assumption is correct, the watchdog killed the app. This is because the app doesn't start up properly and either the main thread is blocked or no user interaction is possible since no UI is loaded.
As I understand your description, you are creating the resources while loading? And probably doing this on the main thread? You should try to offload resource hungry code into a background thread instead of doing this on the main thread where older/slower devices could take much longer than expected. The UI should always be responsive, the main thread should never ever to tasks that could get anywhere close to one second of processing.
Another reason could be that the link between the storyboard and the view controller is broken and it actually never loads on that device type.
But without more details it is impossible to say what exactly is going on.
In general: If the app is killed by the iOS system, e.g. by the watchdog due to startup time exceeding or due to allocating too much memory, then only iOS can generate a crash report.
The problem is that the app gets killed and in that case the process is killed. And that cannot be detected by any code running inside that process. And since crash reports on iOS, other than the iOS system based crash reporter, do run inside the same app process that is being killed, they cannot report or write any crash report.
The following page gives some more details on this: http://support.hockeyapp.net/kb/how-tos-faq/which-types-of-crashes-can-be-collected-on-ios-and-os-x (Though with context to PLCrashReporter, which is not used by Testflight. But the general statements are identical)

Need more memory for my iPad app

I am working on a mail client on iPad (similar to that of the default app client) and using core data framework as a cache to increase performance . My app uses around 4.5 - 5 MB of heap memory and then it crashes because of memory overflow (detected this using allocation instrument). If I try to reduce memory my performance becomes very slow and sluggish because I am not able to cache my views, data structure (which store folders and all the mails) and tableviews.
I have checked my crashLogs and I see jettisoned written in front of my App which confirms that OS has forcefully closed my App!
I have used instrument to detect these limits. Please find the attached image here
This is a snapshot my recordings just before the app crashes.
I have tested my app on simulator and it stabilizes itself at 6 - 7 MB of heap memory.
Is there any way so that I can ask OS for more memory or avoid crash with a little redesign in my code.
Any suggestions or help would be highly appreciated.
6-8MB of memory should never be a problem. Likely you are either trashing memory or if you are running a debug version and have Zombies turned on, the default is to never delete the zombies. NSZombiesEnabled=YES and NSDeallocateZombies=NO will appear to leak memory as nothing is ever deleted.

Core Data lightweight migration crash

I updating my database with a lightweight migration. If I do the update on my device through xcode in debug mode everything runs fine. If I load the app through iTunes as a archive file it will crash before loading the rootViewController. This only happens with my large test database >100mb. I don't get anything useful in the crash log and am not sure what to do with this.
His is the only relevant line I can find in the crash log.
Unknown thread crashed with unknown flavor: 5, state_count: 1
Normally this would be reflected in the crash report (It would say something about failing to launch in time) but iOS devices expect you to get a view on the screen (or for ApplicationDidFinishLaunching to finish, I'm not sure exactly what it looks for) in a certain amount of time or it just gives up and closes the app. If you are doing a significant amount of work you'll want to get some kind of screen up before you start that work. Unfortunately this doesn't happen in a debug environment so it's a pain to test.

Memory footprint of an app on iPhone

I recently had an app rejected from the app store because of Low Memory Exception. The app doesn't leak memory, but its base memory footprint seems to be too high. According to the crash logs sent by apple, it was taking about 14000 pages in the memory (mostly due to huge textures). There were 2 strange things though:
I tested it on 5 devices rigorously before submitting, and never got this crash on any one of them.
I did optimize the textures after the rejection, and brought them to about half the original size (texture memory consumption).
I have no way of knowing how many pages my app is taking now, unless I can reproduce the same crash as apple (which I never could). Is there another way to be able to find out the memory footprint of my app, so that I can be sure that it is optimized enough now.
I did try instruments, but my app crashes when I try to run it through my XCode (must be some problem with my XCode). But it works perfectly when I run it directly on my iPhones/iPods. Any help in finding out the memory footprint of my app on iPhone (if there is something analogous to task manager of windows), would be appreciated.
Thanks
EDIT:
Launching the app from XCode gives the following error in the console:
"Error launching remote program: failed to get the task for process 553."
Launching the app with Activity Monitor gives the following error:
"Target terminated too early to collect data"
EDIT2:
I was able to run my app with Activity Monitor, by using a dev profile instead of distribution profile. But now there are several sections in the Activity Monitor - Physical Memory Used, Real Memory, Virtual Memory. Which one of these do I consider. To sum it up, I need to know which one of these causes the iPhone to throw a Low Memory exception.
XCode -> Run -> Run With Performance Tool -> Activity Monitor.
If the device is connected, Activity Monitor runs on the iPhone/iTouch.
I think you're coming at this from the wrong angle. You're asking how to find the memory footprint without using XCode. I think the question you should be asking is: why can you not use XCode? Presumably that's what you used to develop the application in the first place?
Without XCode you're pretty much flying blind. You say you halved the size of your textures, but how do you know? Does your app release any extraneous memory when it gets a low memory warning? (applicationDidReceiveMemoryWarning:)
First, have you looked at the crash logs from when you run your app from XCode? You should be able to see them in the Organiser in XCode.
I'm not sure there's a single solution to stop your app crashing with XCode. Normally when my iPhone won't allow debugging I just restart xCode and my handset and it starts working again. Restarting XCode sometimes helps. I would also try reinstalling both XCode and the iPhone SDK.