Unexplained Crashs (in Fast Lists) Part 1 (and only for now) - UPDATE

UPDATE This crash seems to have stopped occurring since iOS 7.1 was release. At this time (4th April) I haven't seen any occurrences on iOS 7.1 when I was seeing it more about weekly on iOS 7.0x. Several other crash types have also not been observed on iOS 7.1 although two instances of a different crash have been seen.

Most software crashes sometimes and unfortunately this includes Fast Lists. At the moment I have records of 12 crashes in the latest version (2.04) that was released about a month ago (18th Feb). On many occasions crashes are clearly caused within the software I have developed whether due to my mistake or the libraries (both Apple and 3rd party) that I use having bugs and not and not behaving as documented.  This post is about several crash reports that appear to be occurring deep within Apple's code (although quite possibly due to my own incorrect software), it includes the crash reports very slightly redacted and what I have currently deduced about the cause.

I think the general interest in this post for non-developers will be pretty close to zero.

Just written my first custom UIGestureRecognizer

HFRotationalPanRecognizer is for handling rotational drags and you can find it here. I needed it for a fixed wheel where the two fingered rotation would be inappropriate and confusing. It is suitable for wheels, dials and other fixed rotating issues.

It wasn't too bad once I had my head around it. This article and Erica's book (well I have the iOS 5 version) helped. The key things to remember are to set the gesture state for each move in the gesture as that triggers the update. I also used the same style as the UIPanGestureRecognizer for reporting the move by accumulating it through the gesture but allowing it to be reset by the handler for incremental updates.

I did have quite a bit of trouble sorting out the origin and finished with it settable but always in the superview's co-ordinate space.

UIDynamics - The gotcha!

Make sure you remove all behaviours before directly manipulating a View.

I've been using the iOS 7 framework in a little app I've been writing this week and I was having problems which turned out to be because I wasn't removing all the behaviours from the View before directly transforming it (while it was being dragged).

This includes behaviours that you wouldn't expect to be affected such as UIAttachment anchors pinning the centre of the View to the point which the direct transformation was rotating it. As soon as the dynamic behaviour wants to update the view it will put it where it thinks it should be ignoring all your transformations. Basically (probably for valid performance reasons) the UIDynamics ONLY reads the view's properties when behaviors are added to the view.

It would be nice if there was a call that you could make (either to behaviours or to the UIDynamicAnimator) to inform it of updates to a view so that it could refresh rather than tearing everything down and setting it up again, maybe iOS 8.

Generating all the icons you need quickly from SVG files - SVGtoIcons

The SVGtoIcons project that I mentioned a couple of posts ago is now in a reasonable state for use by others. I've just added documentation that should make it fairly easy to use.

What is it?

A simple script of less than 150 lines of commented Ruby that use Inkscape to convert SVG files into all the sizes of bitmap (png) that you need. It was written primarily to help me complete the release of Fast Lists 2.0. Inkscape is a nice free (and Free) tool but the export UI made it annoying to create lots of different size bitmaps and I didn't know of a good way to do minor non-destructive changes to the shape of the page that you want to output keeping the drawing centred. This script makes it easy.

While I created it to help with iOS app icons and launch screens it can be used for any particular size outputs. When I use it I generate a couple of icons used within Fast Lists in addition to main App Icons and launch icons.

Why should I care?

Well if you have a designer to create every icon from scratch for each size (iPad, iPhone, portrait, landscape, retina, non-retina and for each context it is used in) then maybe you don't need this. But if you have to create the icons yourself generating them from Scalable Vector Files should produce better results than resizing bitmaps. This helps you do that process quickly.

How do I use it?

The most annoying bug - Or Why Fast Lists 2.0 is late

TL;DR - Warning, long rambling description of the winding path of development of version 1.79

Trying to be bug free for iOS 5 and 6 users was harder than expected caused by a mixture of bad luck, Apple's bugs and my own mistakes. I felt a need to write it, you shouldn't feel the need to read it!


Fast Lists was originally released support iOS 5 and later so that I could take advantage of the latest features when I initially developed it. None of the new iOS 6 features were adopted but when iOS 7 was announced some of the features were things that I really wanted to use, particularly the new design which I wanted to properly support along with Dynamic Text and the ability to change the size of the text with the system settings. This version will be Fast Lists 2.0

While the Apple App Store knows about the compatibility of updates with older versions and won't let users update to a version not built for that platform there is no way for any further updates to be made (without it being an update to the users of the latest version too).

After version 1.60 I was receiving two forms of feedback about issues:

  1. Crash reports including a stacktrace when the app actually crashes (these are received automatically from users who have not disabled them "Usage reporting" in the Settings.
  2. In the event of some error conditions that I have foreseen as possible (although unlikely) Fast Lists asks the user to send me some information by email. The email is largely pre-composed with some information about the error but also gives the opportunity to provide additional information AND importantly allows me to respond to the email and ask the user further questions about what happened and potentially offer assistance at times. For serious errors normally where there is risk of data corruption Fast Lists will quite (via calling abort) rather than risk continuing in an inconsistent state.

Both mechanisms have different advantages, the crash reports are automatic and can often give very exact locations where the crash occurs. The email allows follow up with the user about what was happening but provides less technical information and only a small proportion of those who suffer from issues send the email.

The Plan

I decided that the long term cost of maintaining compatibility and two code paths for all areas where iOS 7 features would not be worth it given the speed of adoption of new iOS versions historically. So from the time of announcement I started working on a branch intended to make use of the iOS 7 features. Despite this decision to go iOS 7 only for future versions I didn't want to leave existing users who couldn't or didn't want to update with a poor product so I was determined to crush all the bugs and at least leave a very stable version.

The split actually started with the 1.60 release on 24th June 2013 which I was actually hoping might be the last release for iOS 5 and 6. As it has turned out there were actually another 14 releases after that before I could get to a position where I am happy to release the Fast Lists 2.0 update. 

The Reality

1.60 was a major change that removed the use of the Parse platform for logging because it had been bought by Facebook (see previous post). It also added the use of PLCrashReporter and JIRAMobileConnect as a partial replacement for Parse, specifically the crash logging which it did somewhat better than my previous solution although without logging some non-crashing errors.

This meant several latent issues were revealed that led to a further sequence of updates to fix issues that were revealed (some of which were caused by a mistake in the way I added the crash reporting). After that 1.60 release bugs were squashed one or two at a time and in parallel I was working on version 2.0 to properly adopt the new design and handling the variable sized text.

The software was improving and number of crashes falling until when iOS 7 was released I was getting a significant number of issues saving on that platform with an error regarding conflicts when there was actually no reason a conflict should have been reported. I was not able to reproduce the problem on my test systems.

1.73 - Xcode 5.0 and NSMergeByPropertyObjectTrumpMergePolicy

To resolve the problem of conflicts during saves I changed the mode of saving to specify that the current in memory version should be prioritised in the save (NSMergeByPropertyObjectTrumpMergePolicy) rather than raising an error on save problems. I also used Xcode 5 to build this version which turned out to be a mistake for several reasons. The most obvious reason was that this introduced the iOS 7 look and feel but without the proper modifications that I had made to make the design really work well with Fast Lists (I should have realised that this would happen and probably retained Xcode 4.6). The other reason was that this exposed me to a bug but it would be some time before I discovered that.

As soon as it hit the App Store I found that it seemed to have resolved the issues that I was having on iOS 7 unfortunately it became apparent over the few days after the release that I was now having problems while saving on iOS 5 and 6. Again I could not reproduce this locally and additionally I no longer had any iOS 6 devices with which to test.

1.74 - Xcode 5.01

This was a very quick release that wasn't a major change but used Xcode 5.01 to build in case it resolved the crash reports I was suffering from on iOS 5 and 6. I was only receiving crash reports initially and they hadn't isolated the issue, (although I hadn't realised it they were in fact referencing the location where I was aborting on serious errors after the users had been offered the option of emailing me). 1.74 didn't help at all.

The Assumption

Quite naturally I assumed that the small change that I had made in 1.73 at exactly the place in the code where I was now seeing errors was to blame. It is usually the change you make in the software that is to blame when a problem is introduced. So while I couldn't reproduce the problem I did the obvious next step and reverted the behaviour except for iOS 7 (where this problem wasn't happening and the previous problem seemed to be resolved). As it turned out this didn't actually help at all!

1.75 - Make NSMergeByPropertyObjectTrumpMergePolicy iOS 7 Only

By this time I had received some emailed error reports showing validation errors errors on iOS 6 were happening. The errors I received were like this:

Error UUID: 1510B4F6-0E85-44D0-8DCC-2D5A269EA66A
App UUID: 3E982994-4315-4E76-BB21-6BDF25E37BC6
Error Message: "Apologies but it has not been possible to save your last change.  Please inform support@human-friendly.com about this issue with any information that you have about what caused it."Error Details:
Error Domain=NSCocoaErrorDomain Code=1570 "The operation couldn’t be completed. (Cocoa error 1570.)" UserInfo=0x1d849b70 {NSValidationErrorObject=<TopLists: 0x1c54cd70> (entity: TopLists; id: 0x1c588d20 <x-coredata:///TopLists/tB6F75849-4766-4605-BE60-8AFB2BBC95B22> ; data: {
    list =    (
    name = nil;
    parent = nil;
}), NSValidationErrorKey=name, NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1570.)}
Model: iPad
Model: K94AP
SystemVersion: 6.0.1
App Version: 1.74
Bundle Version: 1.74
Free Disk space: 7329200KiB
Now this report is more useful than I had realised. I save the updates that I have made from many different areas of the code (every update from a new item, a name change, a deletion or even ticking or unticking a checkbox) but I should have taken the error at face value and looked for where toplevel lists (the only time parent should be nil) are saved and particularly at their creation to verify any potential sources of nil names and try to reproduce in the simulator but I focussed too much on the the idea that it was a Core Data problem.

1.76, (unreleased 1.77) and 1.78

These releases fixed a number of other issues (related dragging lists on iPads, iOS 7 layout issue, and a fix for deletions) and added a stacktrace to the emailed error reports. Then I had to wait for an email report with the new error information.

It finally arrived on 29th November (and actually it is the only emailed report form the 1.78 version I have received even now since 1.78 was released on 21st November) so I am very grateful to the reporter.

Error UUID: F4935501-D278-46CE-8257-DADB5A3CD7FD
App UUID: 6B900CD9-7FD4-42A6-A9D9-D0DEBECA2F6E
Error Message: "Apologies but it has not been possible to save your last change.  Please inform support@human-friendly.com about this issue with any information that you have about what caused it."Error Details:
Error Domain=NSCocoaErrorDomain Code=1570 "The operation couldn’t be completed. (Cocoa error 1570.)" UserInfo=0x1ddad030 {NSValidationErrorObject=<TopLists: 0x1ddb9f50> (entity: TopLists; id: 0x1ddb3250 <x-coredata:///TopLists/tAC51B92C-A320-44BA-9D91-27EBA6E0C4322> ; data: {
    list =    (
    name = nil;
    parent = nil;
}), NSValidationErrorKey=name, callStackAddresses=(0x35785 0x3565d 0x333f9 0x3664d0c5 0x3664d077 0x3664d055 0x3664c90b 0x3664ce01 0x3656b421 0x3472f6cd 0x3472d9c1 0x3472dd17 0x346a0ebd 0x346a0d49 0x382532eb 0x365b6301 0x2f823 0x2f7d8), NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1570.), callStackSymbols=(
0  Fast Lists                          0x00035745 Fast Lists + 55109
1  Fast Lists                          0x0003565d Fast Lists + 54877
2  Fast Lists                          0x000333f9 Fast Lists + 46073
3  UIKit                              0x3664d0c5 <redacted> + 72
4  UIKit                              0x3664d077 <redacted> + 30
5  UIKit                              0x3664d055 <redacted> + 44
6  UIKit                              0x3664c90b <redacted> + 502
7  UIKit                              0x3664ce01 <redacted> + 488
8  UIKit                              0x3656b421 <redacted> + 5768
9  CoreFoundation                      0x3472f6cd <redacted> + 20
10  CoreFoundation                      0x3472d9c1 <redacted> + 276
11  CoreFoundation                      0x3472dd17 <redacted> + 742
12  CoreFoundation                      0x346a0ebd CFRunLoopRunSpecific + 356
13  CoreFoundation                      0x346a0d49 CFRunLoopRunInMode + 104
14  GraphicsServices                    0x382532eb GSEventRunModal + 74
15  UIKit                              0x365b6301 UIApplicationMain + 1120
16  Fast Lists                          0x0002f823 Fast Lists + 30755
17  Fast Lists                          0x0002f7d8 Fast Lists + 30680
Model: iPod touch
Model: N81AP
SystemVersion: 6.1.5
App Version: 1.78
Bundle Version: 1.78
Free Disk space: 17439224KiB
I could copy the stacktrace into the crash report that matched this incident (identified by the timing of the reports) to symbolicate it. The result was clear that this was happening when the toplevel  '+' button was being used to create new top level lists.

With that information and the validation errors about the nil name I tried it in the simulator and managed to reproduce the issue. It proved to be that instead of enabling the text input field when the '+' was pressed with no name in the field it was trying to create the list with a nil name. This is the relevant function:

-(void)cellButtonAdd:(UIButton *) addButton
    if([[newListCell.nameField text] isEqual:@""])
        [newListCell.nameField becomeFirstResponder];
        [[HFUsageLogger getSharedLogger] incrementCounterForName:@"topListCellButtonAddEmptyField"];
    // Create a new instance of the entity managed by the fetched results controller.
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    TopLists *newTopList  = (TopLists *)[NSEntityDescription insertNewObjectForEntityForName:@"TopLists" inManagedObjectContext:context];
    newTopList.name = [[newListCell nameField]text];
    newTopList.newItem = YES;
    [newListCell.nameField resignFirstResponder];
    newListCellString = @"";
    newListCell.nameField.text = @"";
    NSIndexPath * selected = [self.tableView indexPathForSelectedRow];
        [self.tableView deselectRowAtIndexPath:selected animated:YES];
    [newTopList save];
        [[HFUsageLogger getSharedLogger] incrementCounterForName:@"topListCellButtonAddSucceeded"];
        [[HFUsageLogger getSharedLogger] incrementCounterForName:@"topListReturnKeyAddSucceeded"];
[newTopList save] eventually calls [managedContext save] which is when the error occurs.

This code is actually correct but it was clear that the check at the beginning was not working:
if([[newListCell.nameField text] isEqual:@""])
In the debugger I could clearly see[that `[newListCell.nameField text]` was returning nil (which is clearly not equal to the empty string @""). This is not the correct behaviour; the UITextField class reference for the text says: This string is @"" by default. Testing on iOS 7 shows the correct behaviour (as do iOS 5 and 6 when the app is built with Xcode 4).

Once I had found this the fix was a fairly simple replacement of the test:
if([[newListCell.nameField text] length ] == 0)
In Objective C if you send a message to nil it is safe but does nothing except return nil (0) so whether we have an empty string or a nil value instead of the string this test handles it correctly.


I should have assumed less about the bug and tested more on the simulator (as I don't currently have an iOS 6 device), maybe I could have found it sooner. However I was VERY unlucky to hit a bug affecting a particular combination of build tool and iOS version at exactly the time I made a change that affected the exact functionality where I was seeing errors.
Apologies for such a long and dull post but I needed to get it down.

Are you breaching Open Source Licenses accidentally?

MIT Licenses and Requirements in Mobile Apps

I am not a lawyer, this is not legal advice I only read the plain text of licenses and try to comply.


Much open source licensed software even permissive licenses like the MIT license and the Apache license require a copyright notice to be distributed with derivative works (although the Apache licences definition of derivative doesn't include where linked by name).  In the case of mobile apps you should at least be including the license text in the bundle and to comply with the spirit of the license I think that you should be exposing it to the end user through the interface.

If your app uses PLCrashreporter, Crashlytics, HockeyApp or uses any open source licenses and you haven't carefully thought about presenting those licenses to the user you should read the long version.


I developed the Fast Lists app for the iPhone and iPad.  It is a fairly simple app focussed on use for check lists, shopping, packing, emergency services divers checklists or really anything that you can think of.

Until version 1.60 is released I was using Parse for anonymous logging (including a self implemented crash reporting system) and for managing promotional in-app upgrade codes.  However when Facebook bought Parse I felt that I needed to move away from their services [I may post separately].  I can live without the anonymous logging and promocodes temporarily but I didn't want to be without crash logging as Apple only seems to provide reports when crashes reach a certain frequency that Fast Lists was not reaching

I looked at a number of hosted and self hosted solutions including:

  • Crashlytics
  • Flurry
  • HockeyApp
  • Quincy Kit.net
  • PLCrashReporter (and writing my own server)
  • JIRA and JIRA Mobile Connect Plugin

In the end I picked JIRA largely for reasons unrelated to to this post.

    The Problem

    Most (all?) of these are based on PLCrashReporter and potentially other Open Source software and as far as I know they all comply with the license.  However none of these take explicit steps to bring to your attention your obligations as a downstream user.  At the VERY least you need to be including a copy of the Licence and copyright notice within your app bundle and I think to comply with the intent of the licenses you should be exposing them to the user in some way as while I know that you can ask iTunes to show the .ipa in finder and then you can unzip and explore it I don't think many users would do that.

    MIT License

    The MIT License PLCrashReporter mostly uses says:

    Copyright (c) <year> <copyright holders>

    Permission is hereby granted ...[lots of good stuff do what you want]...

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    [Legalese to say no warranty]

    So if a substantial portion e.g. (the PLCrashReporter library) is included in your app so must the permission and copyright notice.  For this as I read it including in the bundle with no user accessibility may be legal.

    The Apache License

    The PLCrashReporter uses the protobuf-c library which is licensed under the Apache License version 2.0.  This is longer and more detailed and makes clear than simply linking does constitute the creation of a derivative work.  However by including the library in your application you not only link to it but distribute the library.  Clause 4 of the license is about Redistribution and part 4 says:

    If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    Now it may be possible to get around this in a couple of ways, firstly possibly intentionally neither the PLCrashReporter or the protobuf-c one seem to have a NOTICE file so this section may not apply although the material in the PLCrashReporter LICENSE file is similar to that which I would expect in a NOTICE file.  Secondly even if NOTICE file existed you might just be able to place it within the app bundle under the "within a NOTICE text file distributed as part of the Derivative Works" option only if you did not otherwise have third party licenses appearing within the display generated by the app.

    However even if you use the lack of the NOTICE file part 1 of the same clause says:

    You must give any other recipients of the Work or Derivative Works a copy of this License; and

    So you must at least include the copy of the LICENSE file inside your bundle and not giving them the opportunity to access it would to me seem to break the spirit of the license if not quite its precise language.

    How is this presented by service providers and downstream licenses?

    The closest of the commercial offers to making it clear was probably Crashlytics whose legal page has a link to "Open source licenses" that isn't buried in the text of a long legal document or in a sub-folder of a download.  It doesn't actually seem to be referenced from the legal document so it isn't completley apparent that it needs to be followed by downstream users.

    In fact when I queried Crashlytics about the open source license and the end user requirements and whether I needed to add a licenses section to my app (I'm lazy and I didn't want to spend the time including additional UI on iPhone and iPad) I got this response which I didn't find reassuring about the correctness of the approach although in practice it is probably valid:

    Joseph, great question!

    None of our customers, to my knowledge, has distributed our license with their app and we've seen no cause for alarm so far. That said, it might make sense for you to do so out of an abundance of caution if you are concerned.

    Hope this helps,

      Now I believe that following this advice would technically lead you to breaching at least two licenses. I think as you include the Apache licensed Proto-bufs in your bundle you are certainly distributing even if your app is not a derivative work.

      The Blame and What Should be Done Better

      I'm going to talk about PLCrashReporter because that is the specific software where I hit this issue but I really don't want to pick on them or be making a specific point about them.  Its really about mobile targeted open source.  I really appreciate the PLCrashReporter software that has been provided by the Plausible Labs and they have done nothing wrong but they could help the situation.

      App Developers

      Now we should all read every word of the legal documents we receive, read and understand the details of the licenses for all software we include in our apps so we all share some blame.  For now we need to not be lazy and actually add the UI to our apps to present these licenses (or write all the code ourselves)

      Open Source Library Developers

      I think that the source of the problem is that the original upstream projects set license terms without thinking about them.  I have the feeling that the PLCrashReporter developers don't really expect the license terms to be included with app store apps.  They just used the MIT license because it is standard and permissive.  I think that they should set out their expectations and guidance about how the license should be presented or bundled or possibly even better add additional terms allowing the license to be excluded from mobile apps (and possibly linked to from the developer's site or the app description).

      Now in many cases not thinking about how the documentation would be handled in mobile apps is completely understandable but they are the main target for some libraries such as this so it really should be considered.

      Commercial Services and Downstream Libraries

      The services and derived libraries should include in their user instructions the requirement to add the license to the end user's software bundle. They could even offer a convienience ViewController and Xib to present it (and other licenses if the user needs to show them too).  I think this is the place where the greatest responsibility lies.  These services largely have paying customers whose work is being put into some legal risk, they have a responsibility to their customers to explain what is necessary to comply with the upstream license and it should be in the main how to get started documentation not tucked away in the legal agreement.

      My Solution

      I implemented the license screen in the end.  I want to be squeaky clean.

      My current overall solution is using the JIRAMobileConnect and self hosting a starter licensed version of JIRA.

      You can find the open source code that I have used:

      • PLCrashReporter (not really modifed from the original).

      • JIRAMobile Connect iOS (small modifications from original to support embedding in Xcode project as subproject and git submodule - but that is another story).

      • MinimalGoogleToolbox is a hugely stripped down version of Google Toolbox For Mac extracting only a couple of text processing (particularly JSON) categories for use in my app without bloating the binary.  You could probably use the minimal version and then add other parts in if you wanted to.