Debugging iOS applications in the wild

As iOS developers we have lots of tools to debug our applications. However, debugging issues when the app is on a users device in the wild is much harder.

If the application is suffering from a crash there are good tools to get data via (Twitter Fabric, Crittercism, etc.). However, the problem becomes much harder when the app is impacted by a gnarly bug that impacts the user experience but does not actually crash the app.

The best approach to track down these types of problems is to create a log file that you can write debugging information to and then introspect after the user has experienced the bug. Here is how to do it.

The general approach is:

  • Create a function that will log messages to the filesystem
  • Log appropriate debugging messages
  • Access the log file and determine what the root cause is
Logging Function

This method will write to a file named debugLog.txt in the Documents directory of the app on the users phone.

func logMessage(msg: String) {  
    #if DEBUG
        let dir:NSURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as! NSURL
        let fileurl =  dir.URLByAppendingPathComponent("debugLog.txt")

        let msgWithDate = "\(NSDate()): \(msg)\n"
        let debugMsg = msgWithDate.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!

        if NSFileManager.defaultManager().fileExistsAtPath(fileurl.path!) {
            var err:NSError?
            if let fileHandle = NSFileHandle(forWritingToURL: fileurl, error: &err) {
                fileHandle.seekToEndOfFile()
                fileHandle.writeData(debugMsg)
                fileHandle.closeFile()
            }
            else {
                println("Can't open fileHandle \(err)")
            }
        }
        else {
            var err:NSError?
            if !debugMsg.writeToURL(fileurl, options: .DataWritingAtomic, error: &err) {
                println("Can't write \(err)")
            }
        }
    #endif
}
Access log file

You can then access this file by copying the entire contents of the app from the users phone and navigating to the debugLog.txt file under the Documents directory. Here is a nice animated gif showing the steps.

image Happy debugging!