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!
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!
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.
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.
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.
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.
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.
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 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.
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.
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.
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.
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.
…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.
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; }
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:
![]()
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:
TPCompiledResources.{m,h} into the project, placed within a new group (I called the group “Derived Sources”).DERIVED_FILE_DIR“, display name “Derived Files” and path “$(DERIVED_FILE_DIR)“.project.pbxproj file from within your project’s bundle.TPCompiledResources.{m,h} file sections and delete the “path” attribute for those, too.Now that’s done, images can be accessed by TPGetCompiledImage(@"ImageName.png"). Yay!
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:
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.
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:
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.
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.

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.
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:
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.
launchctl list|grep UIKitApplication|awk '{print $3}'|xargs launchctl remove. And your bootstrap errors magically melt away.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.
For 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:
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!
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:
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.
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.
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.
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:
NSPersistentStoreCoordinator. It seems like a strange scenario that would only be needed in strange situations but the use case turns out to be really common.XMLFetcher class from Classes for fetching and parsing XML or JSON via HTTP)DirectoryLocations category from Finding or creating the application support directory)CGGradientRef from two UIColors (another in a long list of convenience functions that I'm surprised aren't part of Cocoa)UITextFields around to avoid the keyboard)NSScanner)UITableView construction, drawing and management)CheckmarkCell that self-manages radio button style selection (without the UITableViewController needing to do anything when the cell is selected, the cells in the section will automatically ensure only one is selected at a time)MKReverseGeocoder goes the other way but a non-Cocoa approach is needed to go from an address to longitude/latitude)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.
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:

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.
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.
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.
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.
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.

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.
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:

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.

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.
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.
PageViewController templateXMLFetcher
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.

Again, I wouldn't ordinarily draw little design diagrams for this but — its a blog post and big walls of text are boring.
To make the second design iteration work, I go through the following steps:
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 websiteNSManagedObjectContext and used the class to perform lookups on the list of PostcodesResultsViewController for CLLocationManager GPS locationsResultsViewController to switch between the CLLocationManager and user-entered Postcode data sourcesIn 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:
CLLocationManager (gpsLocation in the program)usingManualLocation/postcodeValue in the program)location property on ResultsViewController — a Postcode objectLocation 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.
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 rowResultCellBackground — set as the backgroundView of the cell. Draws the gray gradient background and not much elseResultView — draws all of the text (does not use UILabels) and uses the Gloss Gradient code to construct the backing for the actual price displayThis now brings us a main screen that looks like this:

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).
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.

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.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.
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.
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.
NSPersistentStoreCoordinatorThe 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.
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.
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.
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).
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.
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.
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 tableThe 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.
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.
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.
CheckmarkCell that self-manages radio button style selectionIt'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.
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.
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:
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 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."
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.
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:

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:

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.
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.
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.
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