Crash Analysis with HP AppPulse Mobile on iOS |
Written by Eddie Freeman | |||
Monday, 11 April 2016 | |||
Page 2 of 2
Accessing the NameSetting up your environment from a previously saved state without hitting a server is a pretty common desire. However, if something goes wrong you won't necessarily get much context. We'll demonstrate this when trying to grab the username set from a previous state. Debugging in AppPulse MobileYou launch the app on a new device and suddenly there's a crash. Diving into the crash, it seems like there's a scenario in which launch crashes on app load can happen:
The timeline shows that one of the major events I flagged earlier is causing the problem:
Buggy Block - After checking, I found that I was accessing the wrong key from NSUserDefaults:
func getName() -> String {
Fixed Block - I realized that I'm calling NSUserDefaults too often in the previous snippet and not checking for nil from a forced unwrap.
if let name = defaults.objectForKey("userName") {
In A Threaded TaskA stack trace can get muddled when a threaded task completes or causes a crash later in a program than when it was started. We'll attempt to demonstrate this while collecting the contacts list. Debugging in AppPulse MobileIn this case having intelligently placed breadcrumbs saved me time as I got accurate feedback to focus on where the issue arose. I found the problem during change notification dispatch:
Buggy Block - This led me to find the issue in this block: func contentChangedNotification(
Fixed Block - By protecting the contact object and formatting it properly I am able to resolve the issue: func contentChangedNotification(
A Segfault in TransitTrying to access or write to an illegal memory location can happen to the best of us. We'll demonstrate this when preparing to send the text message. Debugging in AppPulse MobileThe section in AppPulse Mobile makes where this crash happens pretty obvious:
Then I drill down into the timeline to see more: (click to enlarge) Buggy Block - Looking closely it seems like I wasn't checking to make sure the device could actually send a text message: @IBAction func sendText(sender: UIButton) { if !selectedContacts.isEmpty { let controller = GoodFeelsClient.sharedInstance. } }
Fixed Block - Simply adding that check to the conditional resolves the issue: @IBAction func sendText(sender: UIButton) { if !selectedContacts.isEmpty && let controller = GoodFeelsClient.sharedInstance. } else { print("This device cannot send SMS messages.") } }
ConclusionsIn the debugging of each scenario, we demonstrated how usage of breadcrumbs became integral to determine the user behavior that led up to a crash and the originating thread. Even without the breadcrumbs, the organization of crashes by users impacted and by actions causing the crash let me understand at a glance where I needed to focus my attention.
More InformationRelated Articles
To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook, Google+ or Linkedin. |
|||
Last Updated ( Tuesday, 12 April 2016 ) |