swift ios app with firebase crashes when stressed - swift

I have made an IOS app in swift, with a firebase backend database. It works fine, as long as I don't stress the app. It is a rather memory and cpu-consuming application.
If I stress the app with rapid commands however, it crashes occasionally.
When the app is loaded, it populates a tableView with data from firebase, and when I go to the mapViewController, it downloads a lot of Lat/Long coordinates, and creatses polylines with an annotation.
The error I get, is "Fatal error Unecxpectedely found nil while unwrapping an optional".
Now, it only happens sometimes when I stress the app, so my question is:
1:Is it normal that firebase/the app can not handle that amount of data transfer?
2: Would the answer to my problem be to save the data in in file, put it on firebase storage, and afterwards download the file and read the data afterwards.
EDIT: I normally have this error - which is difficult to debug
class AppDelegate: UIResponder, UIApplicationDelegate { Thread 1:
EXC_BAD_ACCESS (code=1, address=0x10)
but just before I could go down the stack trace, and I found this error
this is the way it could look in firebase

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

How to fix loadPersistentStores from crashing on load

I'm trying to develop an app on Xcode that uses core data, however, when I submit the app for test review it crashes on their simulators, but not mine. What's going on here?
For starters, I've recently finished making an app that took a while to develop and went to submit it to iTunes connect. My App was rejected because "we were unable to review your app as it has crashed on launch". I received and symbolicated the line where the crash happens.
https://imgur.com/a/3iX6pqc
The crash happens on line 81 in my App Delegate exactly where I go to get my persistent container and load it in.
https://imgur.com/EzQvnSQ
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "AlarmSavedData")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
print("Here!")
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
I expected that the local database would load in just fine for them, but for some reason, I'm the only one that the database loads in for. I'm able to use it but when the Apple Review team tries to run it, it crashes. Any ideas on what's happening and to do to fix it? The goal is for every user to have their own local database using core data to store their created data.
Crash Log : https://imgur.com/a/rx9doSR
Try resetting the simulator. That fixed it for me:
First of all, ensure that you are testing your app with a simulator of iOS 12.1.4 as indicated in the crash report. The crash report indicates the Hardware to be 1xxx which is apparently some kind of placeholder, not helpful.
I can't explain the crash yet, but here are some clues that might help you find it.
In Apple's TN2151, regarding the EXC_BREAKPOINT type of crash which is what you have, it is stated:
Swift code will terminate with this exception type if an unexpected condition is encountered at runtime such as:
a non-optional type with a nil value
a failed forced type conversion
Putting this together with the fact that the crash occurs in loadPersistentStores() implies that maybe it is not crashing for you because you already have a persistent store on the simulator's simulated disk – that is, you are not a first-time user. App Review is, of course, a first-time user. So you should remove your app's data, in particular the persistent store file(s), from the simulator and test again. Now your test will be more like App Review's.
You should also probably read this answer which discusses a somewhat similar situation.

Get Data to Complication: ExtensionDelegate not Called

(It looks like this issue has been encountered by others in previous weeks, but there haven't been any solutions that I've found.)
I'm trying to do a really basic thing: Get data from either my iOS app or my Watch app to my Complication Controller.
I am turning out to be way less capable of getting this done than I thought. watchOS 2 Transition Guide indicates that I should "[fetch] the needed data from the extension delegate" using the following code:
ExtensionDelegate* myDelegate = [[WKExtension sharedExtension] delegate];
NSDictionary* data = [myDelegate.myComplicationData objectForKey:ComplicationCurrentEntry];
Great. Except, I haven't been able to figure out how to get this to work on the extension side. Though even more importantly, I can't seem to even get the extension delegate code to run at all from a complication controller launch. When I run the complication, I get this message: "Extension received request to wake up for complication support." However, none of the code within any of the extension delegate's methods seems to run. I've also set breakpoints within every method and none of those breakpoints are hit.
It also looks like "transferCurrentComplicationUserInfo:" is also suggested to be used for complication updates, though it's unclear precisely how it's used. As much as I've gathered, it's used to wake up the watch extension so that ExtensionDelegate can store the new data for the next time the complication controller runs, but due to the previous issue I haven't been able to confirm.
I've got one maybe workaround (pinging the server from the complication controller and hoping that session variables persist so I can send relevant data), but there's every chance that if I can't get this worked out my complication work will be hosed. Any help here would be tremendous.
By the way, here's the code I have for "getCurrentTimelineEntryForComplication", if that's helpful at all.
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
NSDate* entryDate = [NSDate date];
ExtensionDelegate* myDelegate = [[WKExtension sharedExtension] delegate];
NSString* data = [myDelegate.complicationData objectForKey:#"meow"];
NSLog(#"complication data: %#", data);
CLKComplicationTimelineEntry* entry = [self getTimelineEntry:#"2015-08-25 00:19:42" entryDate:entryDate complication:complication];
handler(entry);
}
I've been working with Complications in WatchOS2 since Xcode 7 Beta 4. I'm now on the latest, Xcode Beta 6. I've had a number of issues as in both Beta versions running on the Watch, running on the iPhone then installing to the Watch, and running on the simulator frequently give false negatives due to what appears to be buggy APIs and OS releases. I have been able to get data to show on complications in the following way.
Ensure that your primary Interface Controller implements the WCSessionDelegate protocol.
Implement both the didReceiveMessage and didReceiveApplicationContext methods in your Interface Controller.
In your iPhone app, attempt to send a message using the WCSession to the Watch.
If the message fails to send from the iPhone app, send the application context.
Back in the Interface Controller, when you receive a message -or- a context, update the values in your Extension Delegate.
Still in the Interface Controller and still after receiving a message -or- context, get a handle to the CLKComplicationServer and for each complication in activeComplications call reloadTimelineForComplication.
In your Complication Controller's getCurrentTimelineEntryForComplication grab the data you set in the Extension Delegate and set the values in your CLKComplicationTimelineEntry.
This will work usually when the App is already open on the Watch, the app is still resident in memory, but backgrounded on the Watch, or you start the app and their is context waiting which it consumes.
I have not been able to get the historical timeline entries to function (or the future ones). Nor, I have I been able to get the timeline to update independently of the Watch app.
If you are having trouble, here are some debugging things to try. As I stated above, the API and OS appears to be very buggy. The steps below do work (sometimes).
In the sim, use the Reset all Settings option on both the iPhone and Watch sim.
On the device, restart the Watch. If necessary, unpair and repair the Watch, although this takes a really long time to do.
On the iPhone, delete the app (which will also delete the Watch app if installed) and reinstall.
I hope that helps!
Justin
In order to make the ComplicationController respond to WCSession activity you must make the controller conform to WCSessionDelegate, then manage didReceiveUserInfo from within the ComplicationController. The ExtensionDelegate is not woken up for these updates when in the background. You can still update your delegate from the controller if necessary.
Also, as of right now, the simulator does not send transferCurrentComplicationUserInfo to the watch sim, you have to test on devices.

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.

Where is the proper place to initialize data in a core data store?

For an iPhone app that has to have a bunch of data inserted before the user can do their thing on first launch, where is the correct place (in the code) to insert that data? I'm looking at between 700 - 800 records total between a few tables.
I initially tried doing it in applicationDidFinishLaunching:. This worked fine for the iPhone 3gs, but caused a consistent first-launch crash on the 3g. After digging into the problem, i found that on the 3g, the app wasn't responding fast enough (presumably because it was busy dumping loads of data into the persistent store), so the OS was killing it under the assumption it was unresponsive.
To fix this problem, I moved the data initialization process out of appdidfinishlaunching and spawned another thread from the first view controller that shows upon launch. This works most of the time, but every once in a while the app crashes with a 134030 error in core data, which according to the apple constants reference, is:
NSPersistentStoreSaveError
Error code to denote that a persistent store returned an error for a save operation. This code pertains to errors such as permissions problems.
This error pops up when calling save: on the managedObjectContext.
Ideally towards the end of development you would populate this data into a Core Data store and add that to your project. On first run, you then copy that store from the app bundle over as the user's Core Data store. This should work for your case.
In the case where this is not possible, one would perform the import on a background thread.