Planet Cocoa

May 18, 2012

Surfin' Safari

Levi Weintraub is a WebKit Reviewer

Levi Weintraub has been with webkit.org a long time. He’s known for various projects including his bidi work and most recently our subpixel layout support. Please join me in congratulating our latest reviewer!

by Eric Seidel at May 18, 2012 04:06 AM

Safe from the Losing Fight

Testing Pagesmith Footnotes

I have footnotes working in Pagesmith and polished enough that I can show it to other people. I need some help find bugs in the edge cases, so if you’d like to give footnotes a spin before everyone else, shoot me an email: andy at fortunatebear.

by andy at May 18, 2012 12:06 AM

May 17, 2012

Gus Mueller

Quick VoodooPad 5 Postmortem

I was pretty floored by the response to VoodooPad 5's release. I really didn't expect it to make much of a dent- but I was sent tons of positive feedback and sales were much better than I anticipated. The Mac App Store even featured it last week. So thanks to everyone who purchased it and sent in feedback!

Nobody complained about VoodooPad Lite not making the jump to version 5- so I think that was a good move on my part. And swapping out the old page event system with a new one based on JavaScript seems to be a hit. I keep on seeing interesting bits of code that people are writing in VP to automate things.

Another thing I wasn't expecting was the response to adding Markdown as a page type in VP5. Turns out tons and tons of people really wanted this- much more than I would have figured. I think I'll be spending more time in future releases making Markdown even better (5.0.2 has some improvements in this area, as I'm starting to get hooked onto Markdown myself).

I've also recently released VoodooPad 5.0.1 which fixed some pretty important bugs, and I'm currently finishing up 5.0.2. VoodooPad for iOS 2.0.1 was also released today- so if you've been running into any issues with Dropbox syncing, make sure to update.

For fun, here's a couple of recent reviews of VP5:

TUAW: VoodooPad 5: wiki magic
MacStories: Building Our MacStories Wiki with VoodooPad 5
TenOneHundred: VoodooPad 5 Review

May 17, 2012 10:32 PM

May 15, 2012

Cocoa Is My Girlfriend

Unit Testing with Core Data

Whether you subscribe to Test Driven Development (TDD) or another testing practice, when it comes automated unit testing with Core Data, things can be a little tricky. But if you keep it simple, and take things step by step, you can get up and running with unit testing using Core Data fairly quickly. We’ll explore the what, how and why of unit testing with Core Data. We’ll also be using the helper library MagicalRecord. MagicalRecord not only lets us get up and running faster, but helps to cut down on the noise in our tests.

Testing Environment

When you set up a Core Data stack using a file based store (say, using the sqlite store), that file becomes tied to the data model. That is for good reason. Core Data needs to first verify several things before it can use that data store. It must verify the entities have all the attributes the data model expects, as well as to ensure all entities are present in the store. The data and the description of that data must match exactly. However, when you are developing an app using Core Data, this schema changes fast. Adding a new attribute, or even simply changing it’s type can alter the version hashes enough so that the file version and the model version don’t match.

All this is to say that using a file based datastore for unit testing is problematic. Even if you were to set up your file based Core Data model to be auto migrating, it’s still highly likely you’ll perform a refactoring that is simply not compatible with automigrations. Another likely scenario when testing is that you’ll want to create simple test data for a single test, or suite of tests, and then delete it.

While testing with a file based Core Data store is possible, it’s fairly tricky and error prone. Generally, when you setup your test cases, you’ll want to load your sample set of data. When you’re finished, you’ll then want to delete all that data. Unit tests should fail on an error with our application code, not our test infrastructure, setup or teardown code. And besides, I know you’ve already jumped to the same conclusion I have by now, and that’s to use an In-Memory persistent store. Not only are there no file deletions to deal with, you will never have to perform a migration. Since during unit testing, you want a temporary store, the in-memory store is a perfect setup.

Note: Using an in-memory store to perform tests against a Core Data store is not an entirely new concept. Graham Lee has also previously described his process and setup for testing Core Data with an in-memory store.

Quickly Setting up Tests

Now that we’ve gone over a little background, let’s get to how we can use MagicalRecord to easily setup our Core Data tests.

As we’ve discussed previously, MagicalRecord comes with a set of helpers to build a simple Core Data stack for you. We’ll use one that’s fairly straight forward:

[MagicalRecord setupCoreDataStackWithInMemoryStore];

We’ll also want to clean up the Core Data stack after some tests, and, yes, MagicalRecord provides a handy cleanup method for you:

[MagicalRecordHelpers cleanUp];

Let’s explore when and where to incorporate these method calls into your tests.

Testing Frameworks

Up to this point, the discussion hasn’t been geared toward any particular testing framework, although the syntax is common to the SenTestingKit testing framework that is now built in (and a first class citizen in Xcode4). However, there are now several testing frameworks now that provide many structural similarities, while improving on the syntax. Let’s see how things differ across a few of the more popular testing frameworks available for Objective C.

SenTest, OCUnit, GHUnit

SenTestingKit and GHUnit offer a very similar experience from a testing perspective. Primarily, you create a new subclass of SenTestCase, or GHTestCase, and author all your tests in methods starting with the word “test“. You can also run a method before all tests in the class are performed, or before each method.

Depending on how you set up your tests, you have two options on where to put the simple MagicalRecord setup method. If you want a pristine data store for every test (useful for isolating tests), then you’ll want to put this method in the setUp method like so:

- (void)setUp;
{
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
}

However, there are certain cases where you’ll need to preload a larger test data set to test against. I would recommend doing this before each and every test as it will only slow your test runs down. And making tests slower can eventually lead to you not running them at all. I recommend setting this up once per test suite:

- (void)setUpClass;
{
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
}

And to clean up your stack, simply add a call to the clean up method using the appropriate post-test method, tearDown, or tearDownClass.

Kiwi, Cedar

Kiwi and Cedar are the Behavior Driven Development (BDD) style frameworks. Rather than methods, you format your tests using blocks, however there are similar mechanics when runnings tests. That is, you also have ways to setup and teardown your test Core Data stack even if the methods aren’t called setup and teardown. However, with it’s block type syntax, you can have nested setup calls to beforeAll and beforeEach, afterAll and afterEach (the BDD versions of the setup and teardown methods). You will want to place your calls to set up your test core data stack at an appropriate level within your block contexts.

describe(@"MyEntity", ^{
 
  beforeEach(^{
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
  });
 
  afterEach(^{
	[MagicalRecord cleanUp];
  });
 
  it(@"should do something awesome", ^{ /* Put your test here! */ });
 
});

As you can see, setting up and cleaning up after your tests is fairly easy with MagicalRecord.

Supporting Xcode’s Unit Test Support

When using a testing framework like GHUnit, the afore mentioned steps are all that’s required to get started. However, when it comes to using Xcode’s built in unit test bundle, there is one extra step required in order to get the stack setup.

When you first need to load up the Core Data stack, you typically use the method:

[NSManagedObjectModel mergedModelsFromBundle:nil];

This method, give the parameter of nil, will look in the main bundle, which is generally the application bundle, and look for all data model files, and merge those files into a single Core Data model instance for use when instantiating an NSPersistentStoreCoordinator and it’s related NSPersistentStore. However, with the Unit Test bundle, this call does not return the correct answer, as documented by Graham Lee. The solution to this problem is simple: we need to specify the correct bundle so that the Core Data stack initialization process can continue on it’s way. To do this with MagicalRecord, we use the following setUp method for our tests:

- (void)setUp;
{
	[MagicalRecord setDefaultModelFromClass:[self class]];
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
}

The setDefaultModelFromClass: method will perform the solution provided by Graham Lee, which is to load the model from the specified class, which, in turn, is the class of the currently executing test case. And now that we have something more generic, we have the ability to create a very simple boilerplate Core Data unit test case:

//CoreDataTestCase.h
 
@interface CoreDataTestCase : SenTestCase
@end
 
//CoreDataTestCase.m
#import "CoreDataTestCase.h"
 
@implementation CoreDataTestCase
 
- (void)setUp;
{
	[MagicalRecord setDefaultModelWithClass:[self class]];
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
}
 
- (void)tearDown;
{
	[MagicalRecord cleanUp];
}
 
@end

This means that when you begin authoring unit tests requiring Core Data, you can simply inherit from this base test case, and you’re ready to start writing tests.

A Test Case

First of all, it goes without saying that when you’re using Core Data, you create a set of custom entity classes, which are subclasses of NSManagedObject.  And, to make your life easier, you should always use mogenerator to create your custom entities. This is where your custom logic will live. Let’s author a sample test:

@implementation SampleTestCase
- (void)setUp;
{
	[MagicalRecord setDefaultModelWithClass:[self class]];
	[MagicalRecord setupCoreDataStackWithInMemoryStore];
}
 
- (void)tearDown;
{
	[MagicalRecord cleanUp];
}
 
- (void)testSomeCalculationOnMyEntity;
{
	MyEntity *testEntity = [MyEntity MR_createEntity];
	float expectedValue = …;
	STAssert([testEntity customCalculation] == expectedValue, @"expected a good calculation");
}
 
@end

The MR_createEntity method will use the default context that was set up when the setupCoreDataStackWithInMemoryStore method was called earlier on in the test run. This makes for clean tests based on Core Data, but doesn’t let the Core Data syntax get in the way of expressing the intent of the test. And, when the test has completed, this sample entity will be deleted by virtue of the store being released from memory, so that the next test can have a clean slate with which to work.

Conclusion

And with that, you have an extremely simple and fast way to get a test environment setup for unit testing with Core Data. What I enjoy most about this setup is that when authoring unit tests which require Core Data, I am not focused on the details of setting up and tearing down Core Data. Rather, I’m focused on a single entity, and the things it requires in order to work properly. A sample set of unit tests which, in turn, test MagicalRecord itself are included in the MagicalRecord source on github.

 

by Saul Mora at May 15, 2012 09:43 PM

A Tasty Pixel

Compiling Image Resources into a Static Library

I’ve recently been working on a static library for distribution to other developers — Audiobus — and I need to include a couple of graphical resources with the distribution. The usual solution to this is to include the resources separately in a bundle, and require the user to drop them in to their project along with the static library.

I thought I’d see if I could make the process just a little neater, and successfully devised a way to compile the images straight into the library, so the distribution remains nice and clean — just the library itself and a few header files.

Now, I can pop image resources into a folder, and after compiling, access them within the static library with:

UIImage *image = TPGetCompiledImage(@"Button.png");

It automatically handles “@2x” Retina images (although it doesn’t currently do “~ipad” versions).

Here’s how it’s done.

The magic is in a shell script which uses the xxd hex dump tool to create C code that represents the image data as a byte array, then creates around it a set of utilities to turn those arrays into UIImages on demand.

Along with it is a couple of template files — a header and implementation file — that describe the format of the derived code.

Finally, a little tweaking of the project in Xcode (with a brief foray into a text editor to work around some Xcode shortcomings) puts it all together.

Update: Fellow dev Cocoanetics pointed out that they’d solved a similar problem, and have a great write-up on how they create compiled resources using custom build rules on their blog.

The Image Resources

…Just a bunch of png files within a folder inside your project directory. The script assumes there are normal and retina (@2x) versions of each.

The Template

These are the template source files from which the end result will be derived. It contains a few tags that the accompanying shell script will process. I created it in Xcode, placing it within the same folder as the source png images, but removed it from the target’s compile phase, as we’ll be adding the derived source instead.

First the header, TPCompiledResources.h:

//
//  TPCompiledResources.h
//
//  Created by Michael Tyson on 13/05/2012.
//  Copyright (c) 2012 A Tasty Pixel. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
UIImage *TPGetCompiledImage(NSString* name);

And the implementation file, TPCompiledResources.m:

//
//  TPCompiledResources.m
//
//  Created by Michael Tyson on 13/05/2012.
//  Copyright (c) 2012 A Tasty Pixel. All rights reserved.
//
 
#import "TPCompiledResources.h"
 
/*{%IMAGEDATA START%}*/
/*{%IMAGEDATA END%}*/
 
UIImage *TPGetCompiledImage(NSString* name) {
    /*{%LOAD_TEMPLATE%}
    if ( [name isEqualToString:@"ORIGINAL_FILENAME"] ) {
        static UIImage *_SANITISED_FILENAME_image = nil;
        if ( _SANITISED_FILENAME_image ) return _SANITISED_FILENAME_image;
 
        if ( [[UIScreen mainScreen] scale] == 2.0 ) {
            _SANITISED_FILENAME_image = [[UIImage alloc] initWithCGImage:
                                                     [[UIImage imageWithData:[NSData dataWithBytesNoCopy:SANITISED_2X_FILENAME 
                                                                      length:SANITISED_2X_FILENAME_len freeWhenDone:NO]] CGImage] 
                                                                   scale:2.0 
                                                             orientation:UIImageOrientationUp];
        } else {
            _SANITISED_FILENAME_image = [[UIImage alloc] initWithData:[NSData dataWithBytesNoCopy:SANITISED_FILENAME 
                                                                                           length:SANITISED_FILENAME_len freeWhenDone:NO]];
        }
 
        return _SANITISED_FILENAME_image;
    }
    {%LOAD_TEMPLATE END%}*/
 
    /*{%IMAGELOADERS START%}*/
    /*{%IMAGELOADERS END%}*/
    return nil;
}

The Shell Script

Here’s the script that does all the work. The script looks for all “png” images in the given folder, then creates C code representing each image along with wrapper code to give access to the image byte arrays, with help from the template.

This script goes into a “Run Script” phase, placed at the beginning of the library’s build process.

#!/bin/sh
 
# Where the images are (get this from the first "Input Files" entry)
RESOURCES_FOLDER=`dirname "$SCRIPT_INPUT_FILE_0"`
 
# The name of the source template, minus extension
SOURCE_NAME="TPCompiledResources"
 
# Create C arrays, representing each image
tmp="$TEMP_FILES_DIR/compile-images-$$.tmp"
cd "$RESOURCES_FOLDER"
for image in *.png; do
    xxd -i "$image" >> $tmp.1
done
 
# Read the code template
TEMPLATE=`sed -n '/{%LOAD_TEMPLATE%}/,/{%LOAD_TEMPLATE END%}/ p' "$RESOURCES_FOLDER/$SOURCE_NAME.m" | sed '1 d;$ d'`
 
# Create loader code for each image
for image in *.png; do
    if echo "$image" | grep -q "@2x"; then continue; fi
    ORIGINAL_FILENAME="$image"
    SANITISED_FILENAME=`echo "$ORIGINAL_FILENAME" | sed 's/[^a-zA-Z0-9]/_/g'`
    SANITISED_2X_FILENAME=`echo "$SANITISED_FILENAME" | sed 's/_png/_2x_png/'`
    echo "$TEMPLATE" | sed "s/ORIGINAL_FILENAME/$ORIGINAL_FILENAME/g;s/SANITISED_FILENAME/$SANITISED_FILENAME/g;s/SANITISED_2X_FILENAME/$SANITISED_2X_FILENAME/g" >> $tmp.2
done
 
# Create the source file from the template and our generated code
sed "/{%IMAGEDATA START%}/ r $tmp.1
1,/{%IMAGEDATA START%}/!{/{%IMAGEDATA END%}/,/{%IMAGEDATA START%}/! d;}
/{%IMAGELOADERS START%}/ r $tmp.2
1,/{%IMAGELOADERS START%}/!{/{%IMAGELOADERS END%}/,/{%IMAGELOADERS START%]/! d;}" "$RESOURCES_FOLDER/$SOURCE_NAME.m" > "$DERIVED_FILE_DIR/$SOURCE_NAME.m"
 
# Copy the template header file in
cp "$RESOURCES_FOLDER/$SOURCE_NAME.h" "$DERIVED_FILE_DIR/$SOURCE_NAME.h"
 
rm "$tmp.1" "$tmp.2"

The “Run Script” phase that hosts this script also needs a couple of additions, to tell Xcode what the inputs and outputs to the script are: In the “Input Files” section, the path to the image resource folder, with a “*.png” wildcard at the end, and also the path to those template files, TPCompiledResources.{h,m}. Finally, the two output files go in the “Output Files” section:

Screen Shot 2012 05 15 at 20 42 46

Project Setup

Now it was just a matter of setting up the project to include the derived source files in the build. This was a bit messy and took a little doing, but with guidance from this article by Ben Zado on file references relative to DERIVED_FILE_DIR, it wasn’t too painful:

  1. Build, in order to generate the derived source files.
  2. Navigate to the derived sources folder within the build products, and drag the TPCompiledResources.{m,h} into the project, placed within a new group (I called the group “Derived Sources”).
  3. The path type for those files (accessible from the properties viewer — Cmd-I) should be “Relative to Enclosing Group”, and consequently the “Path” field should just show the filename, with no path component. This was a bit touch-and-go for me, and I had a hard time making this happen, so I left it as-is for now, fixing it manually later in step 8.
  4. Under Xcode Preferences » Locations » Source Trees, add an entry with setting name “DERIVED_FILE_DIR“, display name “Derived Files” and path “$(DERIVED_FILE_DIR)“.
  5. Set the path type for the group containing the two derived sources to “Relative to Derived Files”.
  6. Quit Xcode, and open the project.pbxproj file from within your project’s bundle.
  7. Find the “Derived Sources” group (or whatever it was named in step 2), and delete the “path” property from the list of attributes.
  8. I had to also find the TPCompiledResources.{m,h} file sections and delete the “path” attribute for those, too.
  9. Reopen Xcode, and build — it should be good to go (don’t worry that the derived sources are shown in red in the project group — Xcode’ll find them).

Now that’s done, images can be accessed by TPGetCompiledImage(@"ImageName.png"). Yay!

by Michael Tyson at May 15, 2012 08:12 PM

Red Sweater Blog

Permanently Unhide Library

When Apple shipped Mac OS X Lion 10.7, the “Library” folder located within every user’s home folder, which had previously been visible to users in the Finder, was made invisible. To access the Library folder, users must now hold down the option key while selecting the “Go” menu in the Finder.

This is probably a good move for the vast majority of Mac users, but for folks with even a small amount of interest in tinkering with the configuration files and caches of various applications, it’s an outright nuisance.

The nuisance is exacerbated by Apple’s decision to build in the “make invisible” action into every single dot-update to the OS. So if you’ve taken the trouble to undo Apple’s work and make the folder visible again, you’ll notice that when you updated from 10.7.3 to 10.7.4, poof!, it’s gone again.

I solved this very early on for my own needs by adding the command-line instructions for re-showing the Library folder to my Terminal configuration script. Every time I open a new Terminal window, the Library folder is aggressively set to visible again. In practice, this has meant that since 10.7 shipped, I’ve never been bothered once by Apple’s disappearing act.

For less Terminal-intensive Mac users, this solution might not be sufficient. If you, or somebody you love, truly wants the Library folder to be forever visible in the Finder, a good trick is to add a script Login item to do the deed. Here are detailed instructions for achieving this:

  1. Download UnhideLibrary. Make sure it unzips to a script application file after downloading. You’ll need to keep this file around, so I recommend storing it somewhere in your home folder.
  2. Open System Preferences.
  3. Click the Users & Groups icon.
  4. Select the Login Items tab for appropriate user.
  5. Click the + icon and select the downloaded UnhideLibrary script item.
  6. Log out and log back in again.
  7. Never curse Apple’s Library folder policy again.

The script file is just a few lines of AppleScript code to invoke the appropriate shell script. I originally used a plain shell script file but Thomas Borowski noticed it sometimes opens as a regular document at login time. He also wrote his own post essentially stating all the things I’m now repeating here!

So long Library folder, see you again, automatically, on 10.7.5.

by Daniel Jalkut at May 15, 2012 02:20 PM

May 14, 2012

Surfin' Safari

Last week in WebKit: Tab sizing and strings for IndexedDB

A total of 650 commits landed in WebKit’s repositories last week, ending with revision 116915.

Web Inspector’s search box supports CSS selectors again, JavaScriptCore timers will now show up on the timeline and a context menu has been added for tabs.

Text decorations, such as underlines, will now be rendered for text in :first-line selectors. Implementation of the :first-letter selector was aligned with the specification. Eric landed stylesheet inheritance support for seamless iframes, as well as the ability to inherit styles from their parent iframe. The RadioNodeList interface is now supported, background-size is now part of the “background” shorthand and, albeit disabled, the <intent> element has landed.

IndexedDB now uses strings instead of numeric constants. Violation reports generated by Content Security Policy now also include the referer, original policy and the URL which got blocked. The File System API is now able to deal with cross-file system operations, widths and heights are now exposed for <input type=image> images, and the offsetLeft property was broken when used together with CSS Columns.

WebKit has also gained support for the tab-size CSS property. This property, which is also supported by Firefox and Opera, allows you to define the number of spaces a tab should be equal to.

Included among other minor updates on the WebKit website, the conditions under which the WebKit trademark can be used are now available on the Mac OS Forge website.

Other changes which occurred last week:

  • Half a megabyte of memory was saved by Andreas when viewing the full HTML5 specification.
  • The IETC CSS Values and Units tests have been added to WebKit’s test suite.
  • A first step towards implementing the HTML Media Capture API has been made.
  • Pages served with an XHTML-MP doctype will now automatically use a suitable viewport.

by Peter Beverloo at May 14, 2012 02:54 PM

May 12, 2012

Red Sweater Blog

The Sandbox’s Big Red Button

If you’ve been following the debate surrounding Apple’s Application Sandbox, you know that many developers are concerned about the implications for existing apps of adopting the sandbox.

Apple has been threatening for almost a year that apps for sale in the Mac App Store will need to embrace the Application Sandbox, or else further updates to the apps will not be accepted. The deadline for adopting the sandbox has slipped several times, but it currently rests at June 1, 2012. That’s only a few weeks away, and comes just ahead of Apple’s annual developer conference.

I’ve written a few rants about the Application Sandbox, culminating in my February 2012 piece imploring Apple to “Fix the Sandbox.” Slowly but surely, they are improving the technology that drives the sandboxing features of Mac OS X, but by June 1, it appears that many classes of application will still be “unsandboxable” under the current permissions model supplied by Apple.

The shortage of permissions, or “entitlements” in sandbox lingo, has always been at the root of my concerns. Especially because of the political move requiring existing Mac App Store apps to adopt the sandbox, it is easy to imagine a features bloodbath come June, or whenever the requirement goes into place. When Apple announced the postponement to June 1, they also took care to make assurances that bug-fix updates would still be allowed for non-sandboxed apps, which is a nice break, but will still leave many apps to die on the vine in lieu of suitable sandboxing entitlements for the features various apps provide.

Apple publicly documents the list of entitlements available to Mac software developers. One of my major concerns has always been that because the list of entitlements doesn’t cover all the nuanced, legitimate tasks that an app might want to perform on a user’s behalf, that Application Sandbox ran the risk of permanently forbidding certain types of application behavior from being conducted in the sandbox.

The high-level list of Application Sandbox permissions is intentionally coarser-grained than the lower-level “sandbox facility” which ultimately imposes the restrictions. Some developers criticize Apple for failing to embrace the sanbdbox with their own apps, while expecting developers to embrace it for the Mac App Store. On Mac OS X 10.7.4, the two notably sandboxed apps from Apple remain Preview and TextEdit, two apps that would be relatively simple to sandbox compared to a large number of complex, 3rd party products.

But Apple has applied a good deal of sandboxing to their code. For example, take a look at /usr/share/sandbox/ and /System/Library/Sandbox/Profiles/ for examples a variety of “.sb” files that specify the sandbox restrictions of a variety of system services and tools. These files are expressed in SBPL, or the Sandbox Policy Language, which is a scheme-based language used to express the fine-grained permission the sandbox facility is capable of controlling. See my “Sandbox Corners” for a bit more about the lower-level sandbox facility and SBPL files.

Today I decided to take a closer look at one SBPL file of particular interest: /System/Library/Sandbox/Profiles/application.sb. This is the SBPL file that, so far as I can tell, translates the high-level “entitlements” of the Application Sandbox into corresponding lower-level policy expressions for the sandbox facility. For example:

(if (entitlement "com.apple.security.network.client")
    (allow network-outbound (remote ip)))

You can get a taste for how the high level “I’m a network client” translates specifically to “allow out bound ip traffic” at the sandbox facility level. Other high-level rules express much more complex logic. For example, the “I want to use the printer” entitlement translates to a variety of low-level permissions to communicate with printer-system daemons, and read from printer configuration files on the system.

But by far the most interesting entitlement of all is one that I found at the bottom of application.sb. It’s not documented on Apple’s site, and from what I can tell this blog post will become the first Google match on the term. The entitlement is “com.apple.security.temporary-exception.sbpl”, and the comment above it reads simply: “Big Red Button”.

;; Big Red Button
(sandbox-array-entitlement
  "com.apple.security.temporary-exception.sbpl"
  (lambda (string)
    (let* ((port (open-input-string string))
           (sbpl (read port)))
      (eval sbpl))))

This temporary entitlement enables a high-level Application Sandbox-restricted application to supply, along with whatever other high-level entitlements it requests, an entitlement that brings with it as a parameter a literal SBPL program, that will be evaluated and thus applied by the lower-level sandboxing facility.

In short: the Big Red Button gives Apple an out.

Whatever mistakes they make in the devising of high-level entitlements can be theoretically undone after-the-fact by supplying developers with special Big Red Button entitlements that pass along specific permissions to the lower-level sandbox, liberating the application to do whatever important task it needs to do.

Of course, the fact that this facility exists does not say anything about whether Apple will indulge its use. And just because you, as a developer, could use this entitlement key to empower your sandboxed app to do practically anything, it doesn’t mean that Apple’s App Store reviewers would look kindly upon it. In fact, I’m almost positive that at this point, any developer who submits a sandboxed app with this entitlement will have to have already conversed extensively with Apple about the need for such a transgression.

But the entitlement is there, and that makes me breathe a little easier. The Application Sandbox is, so far as I can tell, technically capable of granting whatever permission any app could reasonably need. The only obstacle, and it’s a big one at that, is the political challenge of App Store approval.

Update: John Brayton made an interesting point in the comments, that regardless of MAS policy, the Big Red Button might be useful to non-MAS developers who wish to adopt the Application Sandbox , but can’t manage to squeeze all their functionality into the confines of its entitlements. I originally thought this made good sense, but then realized how risky a move this would be in practice. Because the entitlement in question here has not been documented by Apple, and is furthermore only listed in an implementation file for the system itself, the behavior of this entitlement can’t be relied upon.

Indeed, above I suggested that the entitlement would grant developers the power to enable virtually any capability in their sandboxed apps, but we have no idea how Apple has actually implemented support for the entitlement inside Apple. They could very well have a special case inside the SBPL language evaluator itself that looks for and rejects scripts that it doesn’t recognize as its own.

The application.sb file even has a strong disclaimer to this effect:

WARNING: The sandbox rules in this file currently constitute
Apple System Private Interface and are subject to change at any time and
without notice. The contents of this file are also auto-generated and
not user editable; it may be overwritten at any time.

In other words: you can’t count on the details of this file remaining stable from release to release. It would be foolish to base the behavior of any shipping app on entitlements listed there, but not documented by Apple. I think the Big Red Button is a very interesting find, and I’m very curious about it. But that’s how it should be considered: as a curiosity.

by Daniel Jalkut at May 12, 2012 08:42 PM

May 09, 2012

Safe from the Losing Fight

Illuminate 1.2 Overhauls the Window Switching UI

Illuminate 1.2 is out with major changes to how the cycle windows feature works. Since cycle windows is the main feature in Illuminate, I made an effort to streamline it and make it usable in fewer keystrokes. The most noticeable change is that Cycle (All) Windows and Cycle (All) Tabs have been consolidated into one feature: Cycle Windows. Cycle Windows cycles through all the windows and tabs using just one keyboard shortcut (Option-Tab), plus they’re now grouped by application, making application switching more obvious.

Screenshot1

In order to speed up switching between windows, sticky mode has be turned off by default so the window selection happens as soon as you let up on the modifier keys. Also, there is now a configurable delay between when the keyboard shortcut is pressed and the UI shows up. This means you can quickly switch between windows or tabs without the UI flashing up or otherwise having to wait on it.

The 1.2 includes some other features and bug fixes:

  • Support for Google Chrome tabs

  • Ability to exclude certain applications from the window switching list.

  • You can now change the order windows appear in when switching windows: last time accessed or alphabetical.

  • Improved layout in the cycle windows UI so more space is used by the window thumbnails.

  • Fix for a crashing bug.

The update is free for existing customers, $9.99 for new customers, and is available from Fortunate Bear’s online store or Apple’s Mac App Store.

You can read the full press release here.

by andy at May 09, 2012 05:15 PM

May 08, 2012

Surfin' Safari

Last weeks in WebKit: sub-pixel layout and seamless iframes

Since there wasn’t an update last week, this one briefly covers changes between revisions 114867 and 116271.

Web Inspector now offers the ability to disable all JavaScript execution on a page, and also allows Web Socket frames to be inspected. The shortcut overlay has received some UI polish and the Timeline Frame Mode has been taken out of experimental.

Fixed placeholders have been implemented for date input types, a form field’s entries supplied through a <datalist> are now barred from validation. The Apple Mac port removed support for BlobBuilder and the Selector APIs have been aligned with the specification when pseudo-element selectors are used.

Retrieving a canvas’ image data will now return a Uint8ClampedArray instead of a CanvasPixelArray object. In preparation of supporting getUserMedia on Chromium, the Peer Connection API implementation has been separated with a compile time flag. Tables now support the createTBody() method and the IndexedDB implementation can now open cursors based on an IDBKey, and advance cursors as well.

Eric landed the first parts of support for seamless iframes in WebKit, namely some tests, sandbox and styling and navigation. A vendor-prefixed version of the Performance Timeline API landed, the getUserMedia() method now takes an object instead of a string and the noteOn and noteOff methods of the Web Audio API’s oscillator got implemented.

Antti made it possible to share stylesheet data structures between documents, decreasing memory usage by several megabytes (take note, kling) depending on the port’s implementation. Furthermore, parsed stylesheets may now be cached, increasing performance of subsequent page loads.

Per commit 116009, Levi and Emil were able to close the meta bug for supporting sub-pixel layout in WebKit. While this has not yet been enabled for any port, this is a significant milestone for the project. This article provides some insight in the importance.

Other changes which occurred last week:

by Peter Beverloo at May 08, 2012 02:07 PM

May 07, 2012

Red Sweater Blog

MarsEdit 3.5.1: Tying Up Loose Ends

MarsEdit 3.5.1 is now available on the Mac App Store and directly from the Red Sweater Store. This is a free update for licensed MarsEdit customers.

When I released MarsEdit 3.5 a few weeks ago, it included some very significant overhaul to MarsEdit’s handling of rich text formatting, including new support for customized formatting macros in Rich Text mode.

Given the large number of changes, I was not too surprised that a few annoying bugs snuck in as well. In particular, it became unreliable to apply some formatting options like heading and block quote in Rich Text mode. I took the opportunity while fixing those things to take care of a bunch of other little gotchas, including some more compatibility tweaks for the forthcoming Mountain Lion 10.8 release.

  • Fix the preview window to recognize and substitute template placeholders in the section
  • Fix a bug with Squarespace and Expression Engine not prompting for username/password on new blog
  • Restore ability to set “Warn when no title” option on Blogger blogs
  • Fix a bug that prevented some blog-configuration options from being selected after switching system type
  • Restore ability to start a Header or Blockquote before typing content
  • Pressing return twice to exit Preformatted works again
  • Improve support for future releases of Mac OS X
    • Address an issue with icon view when resizing the Media Manager window
    • Avoid crashes caused by conflicting system libraries

by Daniel Jalkut at May 07, 2012 11:38 PM

NSBlog

Solving Simulator Bootstrap Errors

I'm sure every iOS developer has seen the dreaded bootstrap error. "Couldn't register com.yourcompany.yourapp with the bootstrap server. Error: unknown error code. This generally means that another instance of this process was already running or is hung in the debugger." After nearly throwing my Mac out the window for the Nth time today, I finally managed to come up with a simple fix. Run this in the shell: launchctl list|grep UIKitApplication|awk '{print $3}'|xargs launchctl remove. And your bootstrap errors magically melt away.
(Read More)

May 07, 2012 08:06 PM

May 04, 2012

NSBlog

Friday Q&amp;A 2012-05-04: PLCrashReporter and Unwinding the Stack With DWARF, Part 2

Here I am, yet again! This week, I'm continuing where my last article left off, regarding PLCrashReporter and unwinding stack frames on x86_64. In particular, I go into how I got at and used all the various data I discussed in last week's article, and why some of the existing solutions in the wild weren't suited for our use.
(Read More)

May 04, 2012 06:44 PM

May 03, 2012

Zen and the Art of Programming

RubyMotion brings serious Ruby development to the iOS world

For the past several months I’ve been involved with, but unable to publicly discuss, an exciting project called RubyMotion. My friend Laurent Sansonetti, creator of MacRuby, has now officially launched a serious alternative to Objective-C for iPhone and iPad development.

RubyMotion is not a bridge; it actually generates native applications that are as fast as the ones written in Objective-C . You can check out Ars Technica’s exclusive article for more details on the project and watch the Pragmatic Studio’s 50 minute free screencast about it to get a better idea of how RubyMotion works in practice.

RubyMotionFor a limited time you can buy RubyMotion at an early bird discount rate of 25% off. It’s such a productive and affordable solution, that I’m sure it will quickly become popular among Ruby developers who are interested in iOS development and testing, as well as among existing iOS developers.

Many of the questions you may have can likely be found in the FAQ section, but feel free to ask any additional questions here. Enjoy it.

Possibly related posts:

  1. Is the Enterprise world Rails ready?
  2. Would you use a Mac mini as your development machine?
  3. Mobile Development Marketshare Among Hacker News’ Participants

by Antonio Cangiano at May 03, 2012 04:40 PM

April 30, 2012

Surfin' Safari

Alexis Menard is a WebKit Reviewer!

Alexis (aka darktears on IRC) has been an unstoppable WebKit coder in the last couple of years working at INdT/Nokia Brazil.

Among his contributions would be the Qt multimedia backends with GStreamer/QTKit, improvements to getComputedStyle, and countless other contributions in various parts of WebKit.

We’re happy to finally remove the word “unofficial” from his reviews. Welcome Alexis!

by No'am at April 30, 2012 03:02 PM

April 27, 2012

NSBlog

Friday Q&amp;A 2012-04-27: PLCrashReporter and Unwinding the Stack With DWARF

I'm back once again for Friday Q&A. Today I'm going to talk about some work I recently did on PLCrashReporter, adding support for unwinding stack frames on x86_64. PLCrashReporter was originally targeted solely at iOS, where both ARM and x86-32 (the simulator) make crash reporting relatively straight-forward; we can simply walk the stack via the preserved frame pointer. On x86-64, matters are different, leading to the need to implement support for alternative methods for stack unwinding. This work was sponsored by HockeyApp, to support their upcoming release of Mac OS X sandbox-compatible crash reporting. I'll talk about DWARF debugging information, the compact unwind encoding, and stack scanners. I assume at least some knowledge of x86_64 architecture, for simplicity's sake.
(Read More)

April 27, 2012 02:11 PM

April 26, 2012

Surfin' Safari

Last week in WebKit: The Contributors Meeting and datalists

A total of 652 changes landed last week in various branches of WebKit’s repository. This update covers changes up to revision 114894.

Last Thursday and Friday, Apple kindly hosted the 2012 WebKit Contributors Meeting in Cupertino. With contributors from many different vendors around, a large number of subjects were covered in presentations and discussions. Transcripts of most of these are available on WebKit’s Trac, including a group photo of all attendees.

An experimental Style Panel has been introduced to Web Inspector which mimics the interface of the Script Panel, which also features an open stylesheet-dialog. Cross-frame security error spam when typing in the console is gone, calling document.open() will now reset the Elements Panel and the Inspector is now shimming the startsWith() and endsWith() methods on the String prototype, anticipating implementation of Microsoft’s proposal.

Parsing rules of the :nth-*() pseudo-classes has been aligned with the specification. Clipping issues with the CSS drop-shadow filter have been resolved and the “-webkit-filter” CSS property will now show up when enumerating over an element’s computed style.

Support for the HTML5 <datalist> element has been enabled for Chromium. It provides similar functionality to suggestions by the browser based on what you previously entered in a text field, with the difference that these suggestions are provided by the website.

Other changes which occurred last week:

by Peter Beverloo at April 26, 2012 12:01 AM

April 25, 2012

Surfin' Safari

Abhishek Arya is now a WebKit reviewer!

Abhishek, better known to the community as inferno, joined the WebKit community in March 2010, and he has been fixing security bugs in CSS, DOM, editing, rendering, and various other components in WebKit. Abhishek has contributed more than 260 patches, many of which are fixes to severe security bugs.

Please join me in welcoming Abhishek Arya as a new WebKit reviewer.

by Ryosuke Niwa at April 25, 2012 11:03 PM

April 23, 2012

Gus Mueller

SkyDrive

I just found out about Microsoft's SkyDrive from Macworld: "New and improved SkyDrive is a threat to Dropbox".

Since it works similar to Dropbox, I figured I'd try out syncing a VoodooPad 5 document from Mac to Mac. And sure enough, it worked just fine. I saw new pages being added and modified, without having to close a document.

April 23, 2012 11:26 PM

Cocoa With Love

An RSS-feed and location-based iOS application

The purpose of this post is so that I will have a link to give people when they ask: how do I write an iOS application that pulls data from an RSS feed, displays it pretty and can put things on a map. I'll show you all of that and more as I rewrite my oldest iOS application from scratch: FuelView.

The app presented in this post, FuelView, is freely available on the Australian App Store.

Introduction

I am commonly asked to write a post where I show a basic "pull data from the network and display" application.

But I think "basic" is boring and I try to avoid it in my blog posts. Instead, I decided to rewrite an application that looks simple but actually has a deceptively large amount of work to perform. It's a far better example of a real-world iOS application since there should always be enough work done transparently by your application that it leaves the user with a "Wow!"

The actual application is only 3 screens. While a truly simple three screen application might take about 2-3 hours per screen to implement (even if you're just stumbling your way through), this program actually took me about twice that time to implement (around 15 hours or two full days of programming) and I definitely knew what I was doing, since I've written the entire program before.

If you're curious though, in its first incarnation, this program took me 2 weeks to fully implement — way back in July 2008. It was the first program I ever tried to write for iPhone OS 2.0 and I did a lot of things the wrong way. Having a vague idea what you're trying to do really does make a 5 to 10 times difference to implementation time and unfortunately, the only way to learn is to stumble headlong into things and run the risk of getting everything wrong the first time.

There's a reason why this version is a rewrite from scratch.

Useful code in this post

While the application in this post is only directly useful to people living in Western Australia, I think this is a really interesting project as it contains a lot of very useful snippets of code (some of which I've written posts on before) including:

Plus a whole lot more. It really is a densely packed little program.

So where is all the "useful code"? If you skip forward to the second last section, I reveal where in the program you can find all of these code samples.

About FuelView

FuelView is an application for getting fuel (petrol/gasoline, diesel, etc) prices in Western Australia. It pulls its information from an RSS feed provided by the Western Australian government's "Fuel Watch" scheme that provides fuel prices for all stations in that state.

(No, I don't live in Western Australia — I'm on the opposite coast of Australia — but it seemed like a good idea for an iPhone app at the time.)

The application looks like this:

Fuelviewscreenshots
Download the complete project associated with this post: FuelView.zip (330kb).

Note: the code is all freely available under a zlib-style license but this license does not extend to the other assets. You may not use the icons or application name in your own programs.

The previous version of FuelView (1.1.10 is available for free from the iTunes App Store in Australia. I'll be resubmitting this version (probably 1.2) in a week or two.

Deceptive complexity

It all looks very simple; you get the location from the GPS, you pull the correct RSS feed for the location, stick pins in a map for the result.

If that were the actual number of steps involved, it would be great. However, it's not so simple. Let's take a quick look at the issues that will cause the most trouble for this program.

User location issues

The GPS gives latitude/longitude but the getting the RSS requires a Western Australian suburb name. In order to make this work, you need to be able to look up all the Western Australian suburbs and find the nearest one for your longitude/latitude. This requires a database of suburb names and their longitude/latitude and some code to search this.

Additionally, I want to be able to let the user specify a postcode for their location instead of using the GPS. Again, I need to be able to look up the suburb name for the postcode. Additionally, any code that requires the user's location must be able to tolerate the location being a postcode, not a raw longitude latitude.

A further complication arises because the FuelWatch RSS feed only exists for "larger" suburbs. Names of smaller suburbs can't be used, so the list of suburbs must be filtered to match the list that the FuelWatch website recognizes.

Station location issues

The RSS feed gives the fuel station locations as street addresses but I need longitude and latitudes for them so I can stick pins in the map or calculate the distance between the user and the station.

While this is a similar problem to resolving the user's location, it is actually trickier since new stations appear all the time, so this database must be dynamic (unlike the static postcode database).

I need to actually perform geocoding of fuel stations but there's a problem: Google's APIs are highly restrictive about how often you can make requests. The only way to avoid problems is to pre-populate the database and then have users only perform forward geocoding requests when an unknown fuel station appears and immediately add the new station to the database.

Custom drawing

Then I have the more straightforward complexity of custom drawing. I want to have most of the interface follow a custom aesthetic (because plain is boring) and that takes time and effort. I also need to ensure that drawing and layout function properly on an iPad and an iPhone.

The real design of the program

FuelViewDesign

In the diagram here, the green objects are the 3 main view controllers, the orange objects are the main "model" of the program (being the data that is actually displayed and passed between the ResultsViewController and the MapViewController) and the blue objects are the data controllers or functional pipelines of the program.

You can see some of the "deceptive complexity" here: the ResultsViewController is managing three different kinds of model data, and is also managing input from the CLLocationManager and UITextField. All this is apart from the normal responsibility of showing and displaying the UITableView and its rows.

Initial design of the program

While I'd love to say: I had this entire design ready when I started, it's simply not true. What I actually had was a quick UI design and a quick sketch of the data pipeline.

My inital sketch for the UI looked like this:

FuelViewInterfaceDesign

I didn't really need to do this sketch for this program (since the UI is pretty simple) but it's a good way to start all user programs.

FuelViewInitialDesign

As you can see, in the three years since I wrote FuelView, I had entirely forgotten about the need to resolve postcodes to suburb names and resolve station locations — instead I've simply shown the network pipeline.

This forgetfulness is pretty disappointing. Not only does it make me think the program is taking longer than it should but it ultimately leads to some of the design problems I discuss later.

But we're not there yet.

First implementation iteration

I'm going to refer to the design stages as "iterations". These steps are often called milestones (or mini-milestones when they're this small) but milestone implies you're only going forward, instead of the reality where you normally need to update the existing interfaces on your classes as part of integrating new features — so I prefer to think about it as iterating the program.

The first iteration involved implementing the program as described in the "FuelView Initial Dataflow design" shown above.

  1. Created a new project from my PageViewController template
  2. Pulled in an XMLFetcher
  3. Hardwired the code to pull the RSS feed for a specific suburb
  4. Displayed the list of addresses from the results as a basic text list
Screenshot4

Second design iteration

Now I need to be able to resolve locations from the CLLocationManager to suburb names. I also need to be able to resolve user-entered postcodes to actual suburb names. Finally, there needs to be logic so that a manually entered suburb name supercedes the GPS.

Locationsources

Again, I wouldn't ordinarily draw little design diagrams for this but — its a blog post and big walls of text are boring.

Second implementation iteration

To make the second design iteration work, I go through the following steps:

  1. Modified the CSVImporter from my Writing a parser using NSScanner post to generate a list of Western Australian postcodes with longitude and latitude. At the same time, I need to filter out suburbs that won't be recognized by the FuelWatch website
  2. Brought in a standard class for managing a Core Data NSManagedObjectContext and used the class to perform lookups on the list of Postcodes
  3. Added code to the ResultsViewController for CLLocationManager GPS locations
  4. Added code to the ResultsViewController to switch between the CLLocationManager and user-entered Postcode data sources

Design Mistake #1

In a general sense, the program is "well-designed" but it still contains two design mistakes. I could fix these mistakes but (a) I'm lazy and (b) I wanted to talk about both of them since I think they're under-discussed design problems.

By this point in the implementation, the first mistake has emerged: the ambiguous overuse of the word "location".

Yes, ambiguous naming is a design mistake. It's not exactly an aspect of design that is thoroughly discussed — probably because it's considered self-evident — but as your program evolves and new functions, roles and elements are added to existing classes, it is sometimes necessary to change the names of the classes.

In this program, the word location has a few different meanings:

  • GPS location from the CLLocationManager (gpsLocation in the program)
  • User-specified postcode (usingManualLocation/postcodeValue in the program)
  • Resolved suburb name used for searching (location property on ResultsViewController — a Postcode object
  • The location of fuel stations (instances of the Location class)

Yuck, what a nightmare.

The single biggest mistake here is that the location property on the ResultsViewController is a Postcode object, despite the name implying the Location class. This is an ambiguity you should work really hard to avoid — and fix when it occurs.

A far better approach would actually be: rename the PostcodesController to SuburbsController, rename Postcode to Suburb, rename the suburb property on Suburb to name and rename the location property to suburb. In addition, it would be better to rename Location to Station.

Third implementation iteration

Now that the main data path is working, it's time to start on the custom views.

The GradientBackgroundTable will be the main UITableView class in the program. Its name is a bit of a misnomer: not so much of a misnomer that it's a design mistake but the table can draw as a gradient but can also draw as a flat color — it would be better named "Custom colored background table" or something like that.

Each result row will be represented using the following classes:

  • ResultCell — controller that constructs the rest of the row
  • ResultCellBackground — set as the backgroundView of the cell. Draws the gray gradient background and not much else
  • ResultView — draws all of the text (does not use UILabels) and uses the Gloss Gradient code to construct the backing for the actual price display

This now brings us a main screen that looks like this:

Customdrawing

Note that each row simply shows an orange "cents per litre" line under the price. Ultimately, this should show the distance from the user's current GPS location to the station but since I don't yet have the locations for the stations, I can only show "cents per litre". Note that this "cents per litre" will continue to display in the final program if the user is using a manually-entered postcode (and I don't necessarily know their GPS location).

Fourth implementation iteration

Now I need to resolve station locations. I have the street addresses from the FuelWatch RSS feed results but I need to turn this into longitude and latitude to calculate the distance or stick a pin in a map.

I'll use the Google APIs for this. As I've said though, the Google Maps API won't let you perform a large number of requests per second so I need to aggressively pre-cache station locations and only perform a geocoding request when a new fuel station appears for the first time.

The LocationsController and the Location lookup generally work like the Postcode lookup on the PostcodesController when the station is cached, otherwise, I need a callback when the actual response comes back from Google.

The LocationsController normally uses two Core Data data stores: one is read-only and is the "pre-cached" set of fuel station results (shipped with the application). The second is the read-write data store, saved in the Application Support directory (which is writeable, unlike the application's bundle). This second location will get all new locations for which we need to query Google.

To prepare the pre-cached file of stations that we can ship with the application, the best approach is simply to run in the iPhone Simulator with the LocationController's primary data store set to Read/Write (and the read-only store removed) and when the primary data store fills with results, let it save to file, copy the cached results file from the iPhone Simulator's directory back into the Project.

Once the location is resolved to a longitude and latitude, I can calculate the approximate distance to the user's GPS location, using the approximate kilometres per longitude and latitude at 30 degrees latitude (this is not highly accurate but is sufficient given that most of Western Australia is relatively close to 30 degrees latitude.

With the locations available, I can display the distance in the ResultsView and color code the distance bar based on how far away the station is.

Locationsavailable
Maps Key Note: I have removed my Google Maps API key from the code. If you want to use this code, you'll need to apply for your own Google Maps API key and set it the MapsKey at the top of the LocationsController.m file.

Fifth implementation iteration

Implementing the SettingsViewController to switch fuel types and the MapsViewController to show the current array of results on a map turns out to be very simple. There's not a significant amount of complexity in either of these views.

Design Mistake #2

One point to notice in the implementation of the MapViewController is that I needed to implement an "Adapter category" on NSDictionary to allow the NSDictionary to respond to the MKAnnotion protocol so I could use the dictionaries to display the pins in the map.

How is this a design mistake?

Needing to put categories on generic classes like this is an indication that you probably should have used a dedicated class to contain your data. The results in the program should not be generic NSDictionary objects.

Until this point, the "generic"-ness of the main data type in the program has been ignored. The reality though is that the construction of NSDictionary results from XPathResultNodes and the resolving of station location for each result has been handled by the ResultsViewController — this is all work that a Result class should be performing for itself instead of using a generic NSDictionary class and making the ResultViewController handle all the work.

But ad hoc trickery like adding categories to generic container classes is a big flag that you've forgotten to use a custom class for objects that genuinely need their own behaviors. If you find yourself needing something like this: replace the generic container with a proper custom class.

I'm not saying that adapter categories are a bad idea. Sometimes you can't or shouldn't change the underlying class — in this case and adapter is a good thing. But here in FuelView I can change the underlying class and should, in order to reduce the code burden on our controllers.

So where is all the "useful code"?

An iOS version of my Gloss Gradient drawing code

The GlossGradients.m code is in the project. It's very similar to the original code except that there aren't HSV conversion methods on UIColor like there is on NSColor, so I've had to write these methods myself. It is used in the ResultsView drawing code.

Two persistent stores with one NSPersistentStoreCoordinator

The LocationsController uses two different persistent stores: a read-only store inside the application bundle that is shipped with the application contains the pre-supplied results for station lookups. But the application bundle can't be changed, so I create a read-write store in the Application Support directory. The NSPersistentStoreCoordinator is smart enough to save the store to the correct location automatically.

A full set of "single line Core Data fetch" methods

The NSManagedObjectContext+FetchAdditions.m file contains a range of different fetch request creation methods and single line fetching implementations (for set, array and single object results). It is used in the LocationsController and the PostcodesController to perform the actual queries on the Core Data context.

Getting the GPS location

The ResultsViewController operates as a CLLocationManagerDelegate. The location receiving code is pretty simple but I think the error handling code in locationFailedWithCode: is more interesting.

Pulling data from an RSS feed

Of course, an RSS feed is just XML. We're after the <item> nodes in the result so I use an XMLFetcher to with an XPath query of "//item". You can see this in the setLocation: method and the response is handled in the responseReceived: method (the XPathQueryNodes are turned into an NSDictionary).

Caching data in the Application Support directory

The application support directory is accessed/created in the persistentStoreCoordinator method of the LocationsController. As I said above, this is for writing extra Locations to the Locations Core Data context.

Function to create a two point CGGradientRef from two UIColors

The function TwoPointGradient is pretty simple; it just creates a CGGradientRef taking two UIColors to use as the endpoints of the gradient. However, it's 23 lines of code that don't need to be retyped in the ResultCellBackground, ResultView and the PageCellBackground.

An example of using a category as an Adapter interface

Putting an adapter on a generic container class is a bad idea if you can easily change the class to something of your own implementation. But this is still an example of adapting a class' interface to suit your own needs — something that is very useful when you don't have control over the underlying class.

Scrolling a text field that isn't in a table

The manually entered postcode is in a text field on a UIToolbar and when the keyboard appears, the entire UIToolbar scrolls up with the keyboard. This behavior is handled by the PageViewController (everything below the "Handle the sliding/scrolling of the view when the keyboard appears" pragma except the dealloc method). The PageViewController needs to be set as the delegate of the UITextField for this to work.

A Core Data Postcode database

The PostcodesController shows how to implement a static data store using Core Data. I think I could probably write a base-class for this type of singleton that would dramatically reduce the common code between the PostcodesController and the LocationsController.

A flexible, reusable controller/table/cell structure

The PageViewController, PageCell, all the view controllers and all the table cells are directly based on the code I presented in UITableView construction, drawing and management.

A CheckmarkCell that self-manages radio button style selection

It's strongly reliant on the PageViewController and PageCell classes but the CheckmarkCell shows an easy way (easy for the rest of the program) to manage a section in a table where only one row can be selected.

Forward geocoding using Google's Maps API

The locationForAddress:receiver: method in LocationsController performs an XML request on Googles Maps API to forward geocode addresses into longitude and latitude (the response is handled in mapsResponseReceived:). Again: you'll need your own Maps API Key to make this work.

Conclusion

Download the complete project associated with this post: FuelView.zip (330kb).

Note: the code is all freely available under a zlib-style license but this license does not extend to the other assets. You may not use the icons or application name in your own programs.

The app presented in this post, FuelView, is freely available on the Australian App Store.

I did this rewrite of FuelView for three reasons:

  • I hadn't written any code at work for a week or two — I needed to scratch my codemonkey itch with a few hours of actual programming instead of meetings and documentation.
  • Preparing code like this for my blog motivates me to review my reusable classes and make them more presentable.
  • I'm often asked to show an iOS program that pulls data from an RSS feed.

The first two points are entirely for my own purposes and went fine, thanks.

On the third point — this is definitely code that pulls from an RSS feed. I hope the scale of the program doesn't make it hard to see how the basics work. In addition to RSS feed handling though, there's lot of other code here so I hope there's something here for programmers at a range of different skill levels.

by Matt Gallagher (noreply@blogger.com) at April 23, 2012 10:46 PM

April 21, 2012

Gus Mueller

VoodooPad 5.0 Released

VoodooPad 5.0 is finally out.

You can read about my favorite new features on the FM Blog, and you can download VoodooPad 5 from the VoodooPad website.

It feels really really good to finally release this; VP5 was one of the most difficult releases I've ever done. So much internally has changed, and combined with VP for iOS 2.0 being released at the same time- I'm surprised I didn't kill myself.

Even though Acorn brings in the lion's share of my revenues for Flying Meat (over 90%), I still love using and working on VoodooPad. It works like I do, and it allows me to squirrel away thoughts and info and write my documentation and everything in it. If you're a long time VoodooPad geek, I think you're really going to like this update.

April 21, 2012 07:47 PM

April 20, 2012

Gus Mueller

Forbes: It's Time to End the Drug War

Forbes: It's Time to End the Drug War:

"April 20 is the counter-culture “holiday” on which lots and lots of people come together to advocate marijuana legalization (or just get high). Should drugs—especially marijuana—be legal? The answer is “yes.” Immediately. Without hesitation. Do not pass Go. Do not collect $200 seized in a civil asset forfeiture. The war on drugs has been a dismal failure. It’s high time to end prohibition. Even if you aren’t willing to go whole-hog and legalize all drugs, at the very least we should legalize marijuana."

I'm tempted to quote the whole (relatively short) article since it touches on just about every reason I support full legalization of marijuana.

April 20, 2012 06:49 PM

BBEdit Turns 20

Earlier this month, BBEdit turned 20 years old. I've been using it since 1996 (version 3.5), and I still use it every day.

Congrats to Bare Bones- it's not an easy task keeping software going for that long.

Jason Snell has a writeup about BBEdit's birthday on Macworld as well.

April 20, 2012 05:29 PM

Red Sweater Blog

MarsEdit 3.5: Formatting Macros, Full-Screen Mode, Tumblr Tweaks

MarsEdit 3.5 is now available on the Mac App Store and directly from the Red Sweater Store. This is a free update for licensed MarsEdit customers.

Rich-Text Formatting Macros

When MarsEdit 3.0 was released two years ago, it marked a major transformation in the product. Previously the app was completely focused on providing a means to edit blog posts in HTML, Markdown, or other text based markup languages. With 3.0, I added the long-requested “WYSWIYG” rich-text editing that many customers prefer when working with web content.

But given the considerable work to achieve MarsEdit’s rich text editor, there were some loose ends. One of those loose ends had to do with the very powerful formatting macros available in plain-text mode. These formatting macros are completely user-customizable and allow users to add their own markup templates for virtually any kind of purpose, filling in the details with values from the editor such as the selection, the pasteboard, etc. Various complexities prevented this powerful formatting macro concept from being available to users in rich-text mode.

With MarsEdit 3.5, custom formatting macros are finally available in rich-text mode. I have already discovered some edge cases that don’t work perfectly, but for inserting arbitrary HTML snippets or “wrapping” the selected text in the rich editor with a particular style, these custom macros are very useful. Starting with this release, you can also customize the keyboard shortcut for any formatting macros, whether they are built-in or custom.

The possibilities are limitless, but to illustrate with a simple example, imagine you commonly find yourself wanting green text in your blog posts. The following formatting macro will take whatever text happens to be on the pasteboard, and insert it into the edited post with HTML markup for coloring it green:

Screen shot of the MarsEdit custom formatting macro UI

Lion Full-Screen Mode

Shortly after Lion 10.7 was released, I added nominal support for full-screen mode to MarsEdit. The problem was, it wasn’t very useful for real-world writing scenarios. My mistakes? I merely zoomed the post editor window to occupy the entire height and width of the screen. Most users found this awkwardly huge editor space impossible to work comfortably in, so found themselves avoiding the full-screen mode, even though they liked the idea in concept.

I made a relatively simple tweak for 3.5 that should improve things dramatically. When you enter full-screen mode on Lion, the current width of your editor is preserved, and only the height is zoomed to occupy the full screen space on your Mac. Here’s a shrunken example for the MarsEdit post editor I’m using to write this entry:

Screenshot of MarsEdit operating in full-screen mode.

Of course, it’s easy to imagine a number of ways that full-screen could be even more improved. Incorporating the preview window optionally into the space, offering to hide the Title and other fields, etc. But this is a step in the right direction.

Tumblr Tweaks

I won’t mince words: as a developer, I have a love-hate relationship with Tumblr. The service is immensely popular but in many regards their API (even the newer one, which I admit I’m not using yet) falls short when it comes to providing the services MarsEdit users expect. For example, it’s extremely frustrating that it remains impossible to upload images apart from photo posts. Over the years since I first added support for Tumblr, I have often wondered how much effort I should bother put in, when the service doesn’t seem too interested in catering to offline editing clients. But that doesn’t excuse the fact that many important features are supported by the API, and I haven’t had time to implement support for them yet in MarsEdit. I’m starting to chip away at those now.

MarsEdit 3.5 supports publishing entries to Tumblr as server-side drafts. I decided to tackle this one now because it’s one of the most frequently requested features from my Tumblr-using customers, and because it’s possible to implement correctly with Tumblr’s API. I tried to tackle “queue” type posts with this release as well, but ran into issues with the API that forced me to put that back on the shelf for now.

I also made some minor adjustments to the post editor UI for Tumblr to prevent some issues with Quote and Chat style posts.

Everything Else

I managed to fit a lot of little fixes and nagging shortcomings for this release. It’s hard to quantify all of those little details with much more than a bullet line in a list, so I’m listing the complete list of changes below. Hopefully you’ll just find this release to feel overall more finished and refined than before, and I hope to continue that trend on into the future.

  • Highlighted Enhancements
    • Improved support for Lion full-screen mode
    • Custom Formatting Macros now work in Rich Text mode as well as HTML mode
    • Support for editing Tumblr Draft posts
  • Post Editor enhancements
    • A number of improvements to Rich Text editor to address minor formatting bugs
    • Unified Formatting Macro menu for HTML and Rich Text modes
    • Draggging an image to the post editor now causes inserted image to go to expected target location in text
    • Fixed performance issues that could cause very slow typing in some configurations
    • Fixed keyboard-based text selection in the HTML editor to avoid getting stuck on line endings
    • Fix a slight mismatch in background color between Rich and HTML Text editing modes
    • Work around hanging issues with External Editing in some apps
  • Tumblr-specific enhancemeents
    • Added support for server-stored Drafts
    • Fixed Word Count feature to work properly with Tumblr Quote and Chat posts
    • Revised Tumblr interface for Chat-style posts to prevent formatting problems
  • Other changes
    • Added support for browsing Lightroom 4 libraries
    • New support for unicode characters in URLs
    • Bug fixes for improved Media Manager reliability
    • Fixed an issue where uploaded attachments would fail without prompting for password on authentication errors
    • Added support for authenticated proxy servers
    • Prevent a crash that occurred when working with Blog.de system’s categories
    • Improved XML sanitizing to increase compatibility with malformed blog content
    • Fix a bug that prevented locally added tags from becoming part of the tag-suggestion history

by Daniel Jalkut at April 20, 2012 05:06 PM

April 19, 2012

Miguel's OSX and iOS blog

Key-Value-Observing on MonoTouch and MonoMac

This morning Andres came by IRC asking questions about Key Value Observing, and I could not point him to a blog post that would discuss the details on how to use this on C#.

Apple's Key-Value Observing document contains the basics on how to observe changes in properties done to objects.

To implement Key-Value-Observing using MonoTouch or MonoMac all you have to do is pick the object that you want to observe properties on, and invoke the "AddObserver" method.

This method takes a couple of parameters: an object that will be notified of the changes, the key-path to the property that you want to observe, the observing options and a context object (optional).

For example, to observe changes to the "bounds" property on a UIView, you can use this code:

view.AddObserver (
	observer: this, 
	keyPath:  new NSString ("bounds"), 
	options:  NSKeyValueObservingOptions.New, 
	context:  IntPtr.Zero);

In this example, I am using the C# syntax that uses the Objective-C style to highlight what we are doing, but you could just have written this as:

view.AddObserver (
	this, new NSString ("bounds"),
	NSKeyValueObservingOptions.New, IntPtr.Zero);

What the above code does is to add an observer on the "view" object, and instructs it to notify this object when the "bounds" property changes.

To receive notifications, you need to override the ObserveValue method in your class:

public override
void ObserveValue (NSString keyPath, NSObject ofObject,
			NSDictionary change, IntPtr context)
{
    var str = String.Format (
	"The {0} property on {1}, the change is: {2}",
        keyPath, ofObject, change.Description);

    label.Text = str;
    label.Frame = ComputeLabelRect ();
}

This is what the app shows if you rotate your phone:

The complete sample has been uploaded to GitHub.

by miguel@gnome.org (Miguel de Icaza) at April 19, 2012 10:19 PM