Eric Roller's Development Blog

I have a XCTestCase scenario using the following methodology:

- (void)testScript {
    NSError* error = nil;
    for (NSURL *scriptURL in [self findScriptFiles]) {

        // Read the entire file.
        NSString *text = [NSString stringWithContentsOfURL:scriptURL
                encoding:NSUTF8StringEncoding error:&error];

        // Test each line.
        [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {

            XCTAssertTrue([self runInstruction:line]);

This works, but I don't like it that all error messages are placed in the testScript source code, whereas they should really be placed inline in the parsed script.

I did a bit of digging in the XCTestCase framework headers and found the solution, using recordFailureWithDescription:inFile:atLine:expected:

- (void)testScript {
    NSError* error = nil;
    for (NSURL *scriptURL in [self findScriptFiles]) {

        // Read the entire file.
        NSString *text = [NSString stringWithContentsOfURL:scriptURL
                encoding:NSUTF8StringEncoding error:&error];
        __block NSUInteger lineNum = 0;

        // Test each line.
        [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {


            if ([self runInstruction:line] == NO) {
                // Place the error marker in the parsed file!
                [self recordFailureWithDescription:@"Instruction failed"
                        inFile:[self sourcePathForURL:scriptURL]

NB. The scriptURL points to a file within the resources folder of the test target, i.e. not to the original script file in my Xcode project. I therefore need to locate the original script file, for instance relative to the current source file (whose name can be obtained through the __FILE__ preprocessor macro).

For iOS development, it is necessary to provide a set of app icons of different sizes, all the way from a high-resolution icon for the AppStore to a tiny icon that will be used in Spotlight search results. The trouble is, how to create the icons, again, and again,...

Well, here's how...

Starting off with a 1024 x 1024 pixels source image (in PNG format), one would have to scale it multiple times in an image editing tool, to export it into all the sizes. But can't this be automated with AppleScript?

Well, yes, but it gets better: Use Automator !

I have set up this Automator workflow to create all icon images. It works like this:

  • Launch the workflow in Automator and Run it.
  • You will be prompted to select the 1024x1024 PNG source image.
  • You will be prompted to select a destination folder.
  • Wait...

When the workflow is finished, you will find these files in the output folder:

  • iTunesArtwork@2x (1024x1024)
  • iTunesArtwork (512x512)
  • Icon-1024.png (1024x1024)
  • Icon-512.png (512x512)
  • Icon-60@3x.png (180x180)
  • Icon-76@2x.png (152x152)
  • Icon-72@2x.png (144x144)
  • Icon-60@2x.png (120x120)
  • Icon@2x.png (114x114)
  • Icon-Small-50@2x.png (100x100)
  • Icon-40@2x.png (80x80)
  • Icon-Small@2x.png (58x58)
  • Icon-76.png (76x76)
  • Icon-72.png (72x72)
  • Icon-60.png (60x60)
  • Icon.png (57x57)
  • Icon-Small-50.png (50x50)
  • Icon-40.png (40x40)
  • Icon-Small.png (29x29)

But wait, there's more!

Are you missing an icon size? Just edit the workflow to fit your needs.

Blog Reboot: First Post

- Posted in General by

I have decided to switch my blog to a different backend; one that is easier to maintain and doesn't rely on MySQL (which I always found overkill and difficult to backup). Now I only need to extract my old blog posts from that last database dump file...

Update: Having worked through the dump file in a text editor, I found hundreds of duplicate entries marked as 'inherit' and 'nnn-revision-m'. These entries may be the result of multiple edits of a post. This is exactly the kind of data bloat that I strive to avoid. The current solution stores all entries in simple text files. Easy to back up. Easy to index. No duplication.

Just added a new section to /etc/periodic/monthly/mine.monthly in the attempt to create monthly backups of my subversion repositories, using compressed dump files:

[Update: Now using quoted variable names.] [Update: Now checking "format" file.]

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  for i in * ; do
    # Not a subversion repository? Ignore it.
    if [ ! -f "$i/format" ]; then
    # File: /Volumes/Backups/Attic/svn-file-2014-01-17.dump.gz
    name="svn-$i-`date +%F`.dump.gz"
    if [ ! -f "$dump" ]; then
      echo "Dumping subversion repository: $name"
      # Dump into a gzipped file; "Dumped revision n" into temp file.
      { /usr/bin/svnadmin dump "$i" | gzip -c -9 > "$dump"; } >& "$line"
      # Change the user for the dump file.
      chown gollum:gollum "$dump"
      # Only output the last stderr line then delete the file.
      tail -1 "$line"
      rm "$line"
      echo "Warning: Dump already exists: $name"
  echo "Error: Repositories directory not found."

N.B. I also use TrashLater to keep files for only 6 months in the Attic folder.

For /etc/periodic/weekly/mine.weekly I only dump the most recently modified repository since I don't normally work on multiple projects. This is done with a different foreach loop, where we get just one repository file name:

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  # List the dir by last modified and get the first entry only.
  for i in `ls -1t | sed '1 q'` ; do
    # [...as above...]
  echo "Error: Subversion repositories not found."

UIScrollView vs. AutoLayout

- Posted in iOS by

Setting up a scroll view with multiple subviews (one for each page), I found myself unable to scroll. Everything looked fine. I even had the AutoLayout constraints defined for each of the subviews: pinned width, pinned height, top 0 pt, left x pt (depending on which page).

It took several debugging sessions to work out that the contentSize of the scroll view had been set (through AutoLayout) (after viewDidAppear:) to the size of a single page. Despite my constraints.

The fix is not obvious: there must be constraints for both the top-left corner as well as the bottom-right corner. Once I added an additional constraint for the last view to the right side, the contentSize was correctly calculated to contain all pages.

This tip came from a comment on StackOverflow.

Here are the symptoms: open System Preferences, select Desktop & Screen Saver and click on the Screen Saver tab. In the list of the screen savers, I had an RSS feed which turned out just to be too slow for my aging machine.

However, selecting the feed to delete it just gave me the beach ball, rendering System Preferences totally unresponsive. I gave up after a few minutes. To close System Preferences, click long on its icon in the dock and select "Force Quit".

To delete the RSS feed, I resolved to tracking down the corresponding preferences file and I found this one:


While System Preferences is closed, open the file in a text editor (I like TextWrangler) and delete the feed entry from the dictionary. My resulting file looked like this:


Save the file and reopen System Preferences to verify that the RSS screen save is no longer in the list. Done!

Update: I hear that you also can simply delete the file and you may need to restart or at least logout and login again.

For a while now, I have been puzzled by the fact that Mobile Safari, the iOS version of Safari, opened any page on my web site at a much larger width than the CSS value for the main content area (570px).

It turns out, there are a number of Apple-Specific Meta Tags that can be used to provide background information for your web page, like how to scale it, or providing scaling limits.

To set the initial scaling of a window when presented on the iPhone or iPad, there is the viewport meta tag. If missing, a default width of 960 pixels will be used, or more if the web content is wider. Setting it to 590 pixels, thus adding a 10 pixel padding, works just fine for my particular case:

<meta name="viewport" content="width:590px">

For years, I have had a constantly growing list of shop opening hours in my notes on my iPhone. There has never been a proper place to put them. Until now.

The Open Times iPhone app makes it simple to store all my shop opening times and it is flexible enough to handle any custom combination of when a shop opens and closes (or is open for 24 hours). Best of all, the business hours are presented graphically in a calendar-like view which is an intuitive way to check which of the shops are currently open or closed.

Now that I have entered my data into the app, I have confidently deleted that long entry from my notebook. Success!


- Posted in General by

I see from my web-server log that people like to guess the path to phpMyAdmin in all different variations, colours, shapes and sizes. Now, this is exactly why I have not installed it in a fashion that makes it visible to anyone other than me. Better yet, come to think of it, I have not installed it at all and I don't think I ever will. But if I do, you should probably search for all variations, colours, shapes and sizes of phpMyNeatlyStashedAwayAndHiddenInstallationOfMyAdmin.

Wasted a couple of hours debugging an issue with the use of a custom font on a UILabel; the text simply wouldn't show up on the iPhone Simulator.

No such problems with the (bold) system fonts of any size.

As it turned out, this is an issue (bug) with the iPhone Simulator; when running it on a device, the label is shown correctly.

Also note that there is a "fonts" app and an iOS fonts website that show all the fonts that are available on the iPhone or iPad.