Despite my best efforts to the contrary, I ship software with bugs.
After unit testing and integration testing, the bugs that tend to slip through are tricky ones -- race conditions, crashes triggered by bugs in platform vendor's implementation, and issues that only appear in specific configurations, such as a user synchronizing their iPhone's Address Book with Microsoft Outlook.
These are the types of issues that you hope to catch in beta testing. If you don't, however, these bugs leak into the wild.
On the iPhone, Apple generates crash logs for every third-party application crash. These plain text logs include backtraces, thread state, and other information to help you debug your crashes. Unfortunately, these crash logs are not actually readable by third party applications. As a software developer, you're reliant on users to report the bug (rather than, say, simply delete your application), and then at your behest, synchronize their iPhone, locate the (correct!) crash log on disk, and send it to you.
To solve this problem, I decided to implement our own Crash Reporter. It sports the following features:
If your application crashes, a crash report will be written. When the application is next run, you may check for a pending crash report, submit the report to your own HTTP server, send an e-mail, or even introspect the report locally. Additionally, I hope to add support for services like getexceptional to automatically handle uploading, notification, and tracking of crashing issues.
Crash logs are encoded using google protobuf, and may be decoded using the PLCrashReport API. Additionally, the included plcrashutil handles conversion of binary crash reports to the symbolicate-compatible iPhone text format.
/** * Called to handle a pending crash report. */ - (void) handleCrashReport { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSData *crashData; NSError *error; /* Try loading the crash report */ crashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error]; if (crashData == nil) { NSLog(@"Could not load crash report: %@", error); goto finish; } /* We could send the report from here, but we'll just print out * some debugging info instead */ PLCrashReport *report = [[[PLCrashReport alloc] initWithData: crashData error: &error] autorelease]; if (report == nil) { NSLog(@"Could not parse crash report"); goto finish; } NSLog(@"Crashed on %@", report.systemInfo.timestamp); NSLog(@"Crashed with signal %@ (code %@, address=0x%" PRIx64 ")", report.signalInfo.name, report.signalInfo.code, report.signalInfo.address); /* Purge the report */ finish: [crashReporter purgePendingCrashReport]; return; } // from UIApplicationDelegate protocol - (void) applicationDidFinishLaunching: (UIApplication *) application { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSError *error; /* Check if we previously crashed */ if ([crashReporter hasPendingCrashReport]) [self handleCrashReport]; /* Enable the Crash Reporter */ if (![crashReporter enableCrashReporterAndReturnError: &error]) NSLog(@"Warning: Could not enable crash reporter: %@", error); ... }
The first beta release is now available as open source (MIT licensed) from the PLCrashReporter Project Page. This is intended for developer testing, and your feedback is most appreciated.
If you're interested in additional functionality, integration support, or other development services, feel free to drop me a line. We also gladly accept donations to support our open source development efforts: Donate via Paypal
Plausible Labs' clone of Apple's CoverFlow™ is now available for off-the-shelf licensing.
You can also download a demonstration version of the library (limited to rendering every other cover) to try it out for yourself.
I would (perhaps unsurprisingly) perfer to release the library as open source, but R&D has to be funded! =)
Within a few hours of its 1.0 release, our iPhone application was stripped of its DRM by a customer, and made available via http://appulo.us for use on jailbroken iPhones. Appulo.us serves as a comprehensive repository of pirated iPhone applications, with screen shots, application descriptions, and, of course, links to pirated copies.
The process of stripping DRM from iPhone applications has even been automated.
According to the Appulo.us FAQ, this software piracy serves as a solution to a "flawed app store". In providing pirated copies of our applications, Appulo.us claims that they are providing a justifiable service to our customers -- providing unlimited demos of our applications.
This justification is remarkably prevalent in the community of users that pirate software, as noted in James Bossert's recent blog post of his conversation with an iPhone software pirate:
When i crack an app, any app, i do not do it to hurt developers. Without you we wouldn’t even have our community =) I do this so people would know is an app worth their money.
I agree that Apple should allow demo applications -- users would be better served by the opportunity to test the application. However, this attempted justification does not hold water for one simple reason: as the copyright holder, I am perfectly capable of releasing a demo version of our application for jailbroken phones.
So I will. If you'd like to give Peeps a try on your jailbroken phone, you can download a demo .ipa or app. This version is identical to the latest release, but will display a "Please Purchase Peeps" dialog for 10 seconds when the application launches. (Note! You must have a jailbroken phone to run this Peeps Demo. Sorry!).
This is an experiment. If you like the application, please consider purchasing it. If you don't, let us know what you'd like to see improved. However, please don't distribute pirated versions of our software.