Overview of iOS Crash Reporting Tools: Part 2/2

In this second part of a series on iOS Crash Reporting Tools, you’ll learn how to get started with 5 of the most popular services: Crashlytics, Crittercism, Bugsense, TestFlight and HockeyApp. By Cesare Rocchi.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 6 of this article. Click here to view the first page.

Crashlytics — Running the App

Now that you’ve completed the setup portion, you are now ready to try out Crashlytics. Run the application on your iOS device, swipe on a cell and tap Delete. The application will crash, as expected.

Restart the app and wait about a minute to make sure the crash report has propagated to the Crashlytics server. Then take a peek at the website to see if the crash report is live. You should also receive an email notification about a new crash in your application.

The new issue on the back-end should look like the following:

First issue on Crashlytics

At first glance, you will see the guilty line of code (SMViewController.m at line 80), the number of users affected, and the number of occurrences of this crash. Launch the app and make it crash again. You’ll now see the number of crashes of the same issue increase.

Click the row of that issue and you’ll see the extended report, as shown below:

Detailed view of the report on Crashlytics

Looking at the crash log, it’s clear that you need to counterbalance the deletion of a cell with the deletion of its corresponding element in the array populating the table view. To fix this bug, open SMViewController.m and modify tableView:commitEditingStyle:forRowAtIndexPath: to look like the following code:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [pizzaOrder removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

After you are done, build and run, push the app to your device, and test the application again. Once you have determined that you have fixed the issue, return to the Crashlytics crash report then set the issue status as closed, as shown below:

Crashlytics close bug

On to the second bug!

Crashlytics allows you to add log statements to your code to help track down bugs. Open SMViewController.m and add the following import statement at the top of the file:

#import <Crashlytics/Crashlytics.h>

Next, modify tableView:willDisplayCell:forRowAtIndexPath: in SMViewController.m as follows.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == pizzaOrder.count-1) {
        CLS_LOG(@"posting notification");
        [Crashlytics setIntValue:pizzaOrder.count forKey:@"numberOfPizzas"];
        [[NSNotificationCenter defaultCenter] postNotificationName:LOAD_MORE_NOTIFICATION
                                                            object:nil];
    }
}

CLS_LOG is a macro provided by the Crashlytics framework that enables remote logging. In debug builds, it acts just like NSLog, passing strings to the console. For release builds, the log is sent along with the crash reports and optimized to be as fast as possible. In fact, Crashlytics’ own documentation boasts a 10x improvement over using regular NSLog() calls.

The method also uses custom logging which allows you to store information in key-value form. Think of this as a type of NSDictionary on the web server: you set the values of keys in the code, and you can read the values on the server when hunting down a bug.

In this case you are using setIntValue:forKey, but there are other methods available to store objects, floats and booleans as well. You can find more details about custom logging in the Crashlytics knowledgebase.

Run the application in Xcode and then stop it. Run it again on your device, scroll to the bottom, allow the app to crash, and restart the application after the crash.

The new issue will look like this on the Crashlytics dashboard:

Second issue on Crashlytics

It is clear that this is due to the lack of the method definition loadMore in SMWebEngine.m. If you were to add the definition for this method, and the crash would disappear. Although that’s not the point of this tutorial, so don’t worry about actually implementing it!

Notice that the detailed view of each issue provides information about the device like iOS version, and free space on disk and in memory. All these details might help you when you are hunting down the root cause of a crash.

Click on “More details…” in the middle of the page. This will show even more details like the type of device, orientation, plus the keys and log statements that you have spread throughout your code, as shown in the following screenshot:

Logs and keys on Crashlytics

This way you can have a path of breadcrumbs that can help to hunt down the cause of the crash. It is important to note that logs and keys are sent to the server as attachments to a crash log, so you won’t see them if there aren’t any crashes.

Crashlytics, unlike other services like TestFlight, is not a generic remote logging application, but rather a true crash reporting application. So even though your app may be full of logging statements, if the app never crashes, you’ll never see any of your logs!

One useful feature for beta testing is the ability to ask your users to provide some data to identify themselves. Crashlytics provides three ways to attach this data to a crash log:

[Crashlytics setUserIdentifier:@”123456”];
[Crashlytics setUserName:@”cesarerocchi”];
[Crashlytics setUserEmail:@”cesare@mailaddress.com”];

This way, you can identify who is experiencing a crash, and contact that tester to get more details.

Finally, you can configure some logging features on the back-end. Each application has a settings section that you can open by clicking the gear button, as shown below:

App settings on Crashlytics

From here you can disable reports from a specific version, or request a user for permission before sending data about the report. When you enable it (and you should!), you can customize the message as shown in the screenshot below:

Privacy on Crashlytics

Crashlytics — Summing It Up

This concludes the guided tour of Crashlytics. If you are just targeting the iOS market, I highly recommend that you consider Crashlytics. The service is very quick to upload crashes, there are no hassles with dSYM files, and the back-end service is quite intuitive.

Crittercism is another full-stack tool to keep track of your crash logs. It has been adopted by companies such as Netflix, Eventbrite and Linkedin. It provides support iOS, as well as Android, HTML5 and Windows 8 (which is in beta at the moment).

Crittercism — Configuring the Project

To get started with Crittercism, there are a few steps to follow:

  1. Register an application.
  2. Download and import the SDK.
  3. Configure the Xcode project.

After you login to Crittercism, assuming it’s your first time, you will end up at the following screen:

First step in Crittercism

Tap the big blue button on the top left. You’ll be presented with the following screen:

Creating the first app on Crittercism

This will ask you to assign a name; for this project, put “crashy”. Then select the iOS platform, and don’t bother to invite any collaborators. You’re just testing the application, so choose No for the question “In App Store?”. When you’re done, click the big blue Register App button at the bottom.

Next you will be prompted to download the most recent version of the SDK (which is 3.5.1 at the time of this writing). Here’s the link to the download page, just in case.

Open a new, unfixed copy of the crashy-starter project in Xcode, unzip the Crittercism SDK, drag and drop the folder named CrittercismSDK onto the root of our project, and make sure “Copy items into destination group’s folder” is checked.

Go to the Build Phases tab of the target. Open the Link Binary with Libraries section by clicking on it. You’ll notice that libCrittercism is already linked. Add the SystemConfiguration framework and QuartzCore by clicking on the plus sign, as shown below:

Framework linking in Crittercism

Next, you need to find the App ID. This is the ID for Crittercism and has nothing to do with Apple’s application ID. Head to the Crittercism dashboard, select your application from the list, and click the settings tab on the left. You will see a section that looks like this:

API key on Crittercism

This provides a portion of code to copy and paste into application:didFinishLaunchingWithOptions: of SMAppDelegate.m. First, add the following import statement at the top of SMAppDelegate.m:

#import "Crittercism.h"

Now add the Crittercism supplied code to the top of application:didFinishLaunchingWithOptions: :

[Crittercism enableWithAppID:@"<YOUR_CRITTERCISM_APP_ID>"];

And that’s it, your project is configured to work with Crittercism!

Contributors

Over 300 content creators. Join our team.