Page 2 of 2
Errors on "Done"
Just like "Close," marking a To-do task as "Done" can also trigger errors. This time, however, the kind of errors it can trigger are not only alert messages, but network errors as well.
HTTP Errors
Most first-party web service failures will probably be detected by your server-side monitoring tools. Yet whenever your app is using a third party API, you are potentially exposed to issues in its quality of service. Since users won't make the distinction between what's your responsibility and what isn't, monitoring HTTP errors is crucial for user satisfaction control.
And since we're trying to post a tweet every time a user marks a to-do as "Done," we can get the Twitter API return 403 HTTP errors upon quotas limits, API endpoint deprecation, or message deduplication.
Note that you don't have to add anything to your code for these errors to be reported.
In our case, we decided to also show an alert message if we failed to post the tweet, to warn the user that something went wrong.
Here's the code that does that:
func postTodoOnTwitter(todo:Todo){
guard let todoTitle = todo.title where todo.title != nil else {
return
} self.checkTwitterAccount { (twitterAccount:ACAccount) -> Void in let requestURL = NSURL(string: "https://api.twitter.com/1.1/ statuses/update.json")
let slRequest = SLRequest( forServiceType: SLServiceTypeTwitter, requestMethod: SLRequestMethod.POST, URL: requestURL, parameters: ["status":todoTitle+"done"])
slRequest.account = twitterAccount
slRequest.performRequestWithHandler {( data:NSData!, response:NSHTTPURLResponse!, error:NSError!) -> Void in
if(response != nil && response.statusCode == 200){
todo.tweetedAt = NSDate()
try!self.appDelegate. managedObjectContext.save()
} else {
let errorDesc = (error != nil ? error.localizedDescription : NSLocalizedString( "Unknown error", comment:"Unknown error"))
let title = NSLocalizedString( "Twitter Posting Error", comment:"Error Alert title")
let message = NSLocalizedString( "Could not post to twitter account : \n", comment:"Twitter post error") + errorDesc
let buttonText:String = NSLocalizedString( "Ok", comment: "Ok button")
/* alert view style */
let alertView = UIAlertView( title:title, message: message, delegate: nil, cancelButtonTitle: buttonText)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
alertView.show()
})
}
}
}
}
Failed Action Synthetic View
AppPulse Mobile provides error reporting based on user actions. Instead of simply logging errors per error type on various boards (e.g. list of HTTP errors, list of UI Alert errors, etc.), AppPulse Mobile records which user action is at the origin of these multiple errors, and displays them under a single meaningful entry - one per each type of user action.
By looking at the interface, you can see that the "Done" action has also triggered some errors:
Yet this time, when you dive into the details of this action you can see that both network and UI alert errors are involved:
This type of reporting provides you with a unique user-centric view of the errors, rather than a purely technical one.
App Launch / Manual SDK Error
Many things can go wrong when launching an app. In our example - since we're using CoreData - problems may arise when initializing the local DB. AppPulse Mobile automatically detects and reports crashes and unhandled exceptions, but errors sometimes need to be reported manually using code. For this you can use the AppPulse Mobile framework functions directly.
Here's the full list of methods you can use once you've included the <AppPulsemobile/HPAppPulse.h> header:
+ (void) setScreenName:(UIViewController*) vc screenName:(NSString*)name;
+ (void) setControlName:(UIView*) control controlName:(NSString*)controlName;
+ (void) setControlName:(UIView*) control controlName:(NSString*)controlName withScreenName:(NSString*)screenName;
+ (void) setControlType:(UIView*) control controlType:(HPControlType)type;
+ (void) addBreadcrumb:(NSString *)text;
+ (void) reportCrash: (NSException*) exception;
+ (void) reportHandledException:(NSException *) exception withDescription: (NSString *)description;
+ (void) reportHandledException: (NSException *)exception;
At the moment, only report HandledException is officially supported.
NOTE: When coding in Swift, you may have to bridge the HPAppPulse.h file before using it. For that, first create a "Bridge-Header.h" file that contains only one line:
#import <AppPulsemobile/HPAppPulse.h>
Then, in the build settings of the target, add this file in an "Object-C Bridging Header" entry under the "Swift Compiler - Code Generation" section. You will then be able to use HPAppPulse methods right from your swift code.
In our case, Xcode's template for apps using CoreData already catches thrown exceptions; we simply catch any exception thrown during the persistent store coordinator initialization, and report it.
do {
try coordinator.addPersistentStoreWithType( NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError( domain: "CoreData initialization", code: 9999, userInfo: dict)
// Replace this with code to handle the error // appropriately.
// abort() causes the application to generate a // crash log and terminate. You should not use this // function in a shipping application, // although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \wrappedError.userInfo)")
HPAppPulse.reportHandledException( NSException(name: wrappedError.domain, reason: wrappedError.description, userInfo: dict))
abort()
}
To test this error, we install the app on a device to have it create the DB file, then make a random modification to the core data model (such as adding a dummy boolean field) - and forget to create a migration file.
Here's how the error would appear in the interface:
And here are the details:
We've seen how AppPulse Mobile is able to report most unexpected behaviors - from UI Alerts to HTTP errors - automatically, and group them under the user action at their origin, so that you can easily get a comprehensive view of the features that lead to errors. We've also explored how to manually send errors to be displayed in the AppPulse Mobile interface, should you need it. By using AppPulse Mobile, you can be sure that no error or unexpected behavior will remain unnoticed.
- Benjamin Garrigues is a senior application developer and architect and founder of Simple App, an IT consulting company focused on modern IT architectures answering today's companies needs for service omnipresence at affordable cost.
More Information
HP App Pulse Mobile
Related Articles
Animated iOS User Interfaces
Analytics As A Service
Monitor Mobile
Deep Monitor Your Site
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.
|