iOS Crash When Testing on Device - Debug Logs

Only Crash logs showing in Device Console

(Swift 5.3, Xcode 12, iOS 14 — No need for a third party service or library)

In short: You can replace your NSLog calls with calls to Logger.


You need to create a Logger object (somewhere, your preference). If you want, you can make your logging easier to filter, e.g. in the Console app, by making various loggers for different parts/functions in your app.

import os.log

let downloadLogger = Logger(subsystem: "My app", category: "Downloading")
let somethingLogger = Logger(subsystem: "My app", category: "Lorem ipsum")

Then you call your logger like this:

// Some error occurs, so we log it:
downloadLogger.error("Error downloading feed contents: \(error, privacy: .public)")

// Some less important log:
somethingLogger.info("Secret has been stored: \(mySecret, privacy: .private(mask: .hash))")

N.B. our secret is kept secret by applying .private(mask: .hash).

To view and filter your logs, on the Devices screen, below the View Device Logs you'll find Open Console.

As the article source states:

"If you’d like to gather logs from a device, even when your app is not
running anymore, you can use the log command on your Mac with the
collect option

The logarchive file that you get can then be opened in the Console app and filtered just like live logs can."

sudo log collect --device --start "2020-06-25 16:10:00" --output myapp.logarchive


(Credits: source)

Way to see crash logs for an iOS app outside of an Xcode debugging session?

Can you run your app on a device? If so, you might be able to get the crash data you need from the Devices window, from Xcode.

Xcode -> Window -> Devices.

Select your device, then select View Device Logs.

Here's Apple's page on the subject.

For running in the simulator, you may be able to get the crash data you need from the Console (I've just tried this and seen at least one crash log from my current development).

Here is Apple's page on Testing with the Simulator. From the menu on the left, check out Viewing Crash Logs. Extract from that page...

To view a crash log

  1. Open Console by going to Applications/Utilities/Console in the Finder.
  2. Look for the line in Console that reads “Saved Crash Report for.”
  3. Expand this item using the arrow at the left.
  4. Click Open Report.

iOS crash log catch, debug info.. Catch and send via email to the Dev team

Thanks for all the inputs guys.. I clubbed your solutions into one that would solve my problem.. Here is what I made it to be.. Surely I did not compile the code, it is a half baked code.. but I will iron it soon once as I implement it in my code..

NSLog into file How to NSLog into a file LOG2FILE

#if TARGET_IPHONE_SIMULATOR == 0    
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
#endif

Catch the Crash and Log them too into a File

First, create a function that will handle the error and output it to the console (as well as whatever else you want to do with it):

void uncaughtExceptionHandler(NSException *exception) {    
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}

Next, add the exception handler to your app delegate:

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:  
(NSDictionary*)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); // Normal launch stuff
}

Set a variable in the info.plist called Crashed and then read/write it this way

- (void)readPlist
{
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:localizedPath];

NSString *crashed;
crashed = [plistDict objectForKey:@"Crashed"];
}

- (void)writeToPlist
{
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

[plistDict setValue:@"YES" forKey:@"Crashed"];
[plistDict writeToFile:filePath atomically: YES];
}

Once the app launches read the info.plist and prompt the user to submit the crash logs..

{
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;[mailComposer setSubject:@"Crash Log"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"];
[mailComposer setToRecipients:toRecipients];
// Attach the Crash Log..
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
NSData *myData = [NSData dataWithContentsOfFile:logPath];
[mailComposer addAttachmentData:myData mimeType:@"Text/XML" fileName:@"Console.log"];
// Fill out the email body text
NSString *emailBody = @"Crash Log";
[mailComposer setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}

iOS App crashes on exit, how to debug?

Test it on a real device - if the app crashes, a crash log will be generated. It will be available in the Organizer Window of XCode in Device Logs section corresponding to your device.

That log will give you the call stack of the crash, probably narrowing the places you need to search.



Related Topics



Leave a reply



Submit