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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Overview of iOS Crash Reporting Tools: Part 2/2
50 mins
- Getting Started
- Crashlytics — Configuring the Project
- Crashlytics — Running the App
- Crashlytics — Summing It Up
- Crittercism — Configuring the Project
- Crittercism — Uploading the dSYM
- Crittercism — Running the App
- Crittercism — Summing it Up
- Okay Class — Time for a Break!
- Bugsense — Configuring the Project
- Bugsense — Running the App
- Bugsense — Summing it Up
- TestFlight — Configuring the Project
- TestFlight — Summing it Up
- HockeyApp — Configuring the Project
- HockeyApp — Summing it Up
- Conclusion
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:
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:
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:
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:
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:
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:
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:
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:
- Register an application.
- Download and import the SDK.
- Configure the Xcode project.
After you login to Crittercism, assuming it’s your first time, you will end up at the following screen:
Tap the big blue button on the top left. You’ll be presented with the following screen:
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:
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:
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!