We built an app using React Native to improve UX and features of our previous Cordova app.
Everything went fine. Several months of development, QA, App review and then we published to App Store. It worked on all devices we tried, from iPhone 4s to iPhone 6s+, we tested on iOS 8.3 (earliest simulator you can download through xCode) to 10.0.
After release lots of users started reporting that app crashes before splash screen even goes away. Behaviour we haven't seen in the app review, testing or anywhere else before.
We investigated "crashes" in xCode and they obviously didn't show up, because hundreds of users experienced a crash and we were able to only see few - which seemed unrelated to startup.
We released an updated version with Crashlytics integrated, but that didn't help either. We do not get Crashlytics errors for this specific problem either, meaning that problem is probably happening before
Any ideas where should I look next? We really do not want to revert to the old version and lose months of work.
The app uses around ~100MB of memory when everything is loaded, so that shouldn't be a problem I presume. It is happening on all versions of iOS across all devices. We cannot isolate the error to only specific users.
When there doesn't seem to be any other avenue of analysis, I resort to the humble fall-back of logging.
I have previously used the following technique in production iOS apps. This is a bit of work to set up, but once going it is tremendously useful for many other problems in the future. Not just crashes, but any other strange behaviour that users report which you cannot replicate in your testing environments.
NSLog()
writes to stderr, not stdout.Many variations on this are possible. Including things like only enable logging if the user has configured a setting for it. You may have to add a whole lot of logging around particular areas of code sometimes when a user reports a particular problem, and then delete it again after the problem is resolved (if you are concerned about the performance/storage issues around logging).
For my (Objective-C) app, the places for including my code to write startup status to defaults were as below (there may be better places more suitable for your app):
application:didFinishLaunchingWithOptions:
viewDidAppear
(NOT viewWillAppear
! there's a lot of stuff can go wrong between these two being sent)PS. My old log redirection and rotation method was something like this (Objective-C):
- (void)logRedirectRotate {
// If stderr not going to an XCode console (then running in production)
if ( ! isatty(STDERR_FILENO) ) {
// Rotate logs
int rotationsCount = 3;
NSMutableArray *logRotations = [NSMutableArray array];
for ( int i = 0; i < rotationsCount; i++ ) {
[logRotations addObject:[pathToLogsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"appnameorbundleid.%d.log", i]]];
}
[[NSFileManager defaultManager] removeItemAtPath:[logRotations lastObject] error:nil];
for ( int i = rotationsCount - 1; i > 0; i-- ) {
[[NSFileManager defaultManager] moveItemAtPath:[logRotations objectAtIndex:i - 1] toPath:[logRotations objectAtIndex:i] error:nil];
}
// Redirect stderr to current log file rotation
freopen([[logRotations objectAtIndex:0] cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
}
The problem took so long to resolve because of bad communication between us and our users. App was actually NOT crashing, just not starting up (which is the same in the eyes of some users).
After we discovered that, we realized that one of the events is not firing (the one that hides extended splash screen) and this is where users got stuck. One of the libraries we were using didn't correctly handle the error scenario and it made our job much harder. I was lucky to get into that state while testing and I could continue from there.
I updated the code to handle that scenario and the issue is now resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With