Black Ink 1.4: Printing Blitz

May 20th, 2011

Black Ink 1.4 is now available on the Mac App Store and direct from the Red Sweater Store.

Black Ink is great for solving puzzles on your Mac, but also a fine tool for printing supported puzzle formats in a professional-looking layout suitable for solving on paper. For Black Ink 1.4, I made major strives towards improving the printing features of the app. The major new printing feature is an option to “squeeze” everything for a puzzle onto a single sheet of paper. For larger puzzles this can create a grid and clue list font size that are quite small, but for many folks it’s a priority to get everything on one sheet for easy solving-on-the-go.

Also notable in this release is the return of user-customizable puzzle sources. I removed these in 1.3 because I thought it was more trouble than it’s worth for most users. But for those who do discover sources and are able to configure the settings in Black Ink, this is a much-missed feature.

Complete change list:

  • Printing improvements
    • Support a new “fit on one sheet of paper” print option
    • Support live-updating of print preview as settings are changed
    • Fix issues with printing when clue list printing is disabled
    • Fix a bug where some clues would rarely not get printed
    • Work around a printing issue on a pre-release version of Mac OS X
  • Other Fixes
    • Prevent possibility of crashes with some accidental keystrokes in puzzle view
    • Remove Houston Chronicle as it stopped publishing Mar 25, 2011
    • Prevent double-quoting titles of puzzles already in quotes
    • Further fixes for Mac OS X 10.4 functionality
    • Fix to show puzzle document names as “Black Ink Puzzle Document” in Finder
    • Restore ability to add custom puzzle sources to the default list

Twitter Security Smackdown

May 19th, 2011

Today Twitter announced a few distinct policy changes for clients of their API, all wrapped up under the banner of improved security permissions for end-users. The best response I’ve seen yet is from John Gruber, who smells something funny in the deli. I tend to agree. The announcements today comprise some useful security enhancements, but the security gains from some of the decisions that were announced are not so great that they offset the serious disadvantage they impose on 3rd party developers, particular developers of native mobile and desktop apps.

Let me break the announcements today into three policy change assertions, and how I react to them.

  1. Access to Twitter direct messages will require a new level of user-granted permission. This is a great thing! I recently tweeted that exactly something like this was necessary, because I’ve grown tired of giving every damn service that I wish to connect to Twitter, access to all my confidential direct messages. The new permission allows developers of client apps to state their desired permissions, and those permissions will be listed prominently on your list of approved applications.

    Verdict: Kudos, Twitter.

  2. Developers of Twitter clients will be required to use OAuth in order to gain this new permission. In laymen terms, this means client apps can’t log you in with just your username and password. You will need to be redirected to the web. This requirement is ostensibly because Twitter wants to increase the likelihood that end-users will be made aware of exactly which permissions a client application is requesting. Without this requirement, a native application could claim to seek read-only access, but behind the scenes be using your username and password, by way of Twitter’s xAuth solution, to request a higher level of permission than you intended to allow.

    I concede that this requirement is, on the face of it, an added protection for customers who are wary of providing Twitter credentials to an untrusted app. But here’s the catch with native software: you better trust it, because there is no shortage of ways in which it could screw you. It’s running with some degree of elevated permission on your own device. Twitter putting shackles on native app developers in the name of security is laughable. For example, it would be easy for an untrustworthy native app to provide a custom, compromised browser view that purports to drive a user through the Twitter OAuth permission flow with a given permission, but is actually requesting a different level of permission in a second, undisplayed web flow.

    This is not to say that we shouldn’t bother reining in native software that may be flawed or whose permission we may want to revoke. This is what is so clever about the xAuth workflow, the compromise that allows native apps to authenticate as if by way of an OAuth flow, but using a user’s username and password to facilitate the process. If an end-user or Twitter itself loses confidence in an xAuth based application, they can still revoke access to the application in the same way they would for any other OAuth managed client.

    Verdict: Nice try, but if you don’t trust your native software, Twitter can’t do much to keep you from getting screwed.

  3. These requirements apply unilaterally to all native clients. Except Twitter’s. I grant you, it makes sense for a company to exempt itself from security restrictions that are imposed to prevent “bad guys” from taking control of a user’s credentials and doing damage to the user or to Twitter itself. But this story is complicated by the fact that Twitter entered a competitive market of native clients of its own system, where for years it was not a player, and then proceeded to adopt increasingly developer-hostile attitudes. In particular towards developers of software that aims to fill that coveted role of a “general purpose read/write Twitter client.”

    Is it illegal to do what Twitter has done? Absolutely not, nor should it be. But in my opinion these 3rd party developers were a valuable asset that was pivotal in building passion for Twitter in the earliest years of its existence. Many of the features that we take for granted in Twitter itself were prototyped in 3rd party native applications. Hell, even Twitter’s own native Mac app was itself a 3rd party application (Tweetie) until not too long ago.

    Twitter’s attitude towards these developers seems to be: thanks for all the help, but we’re done with you. The fact that Twitter is willing to “whitelist” their own apps further suggests that this may not be a pure security play. Only legitimate developers of trustworthy apps would be interested in seeking an API key to connect to Twitter. If your aim is to write malevolent software that abuses Twitter or its users, you should be content to take an app like Twitter’s own Mac client, extract the portions that communicate “securely” with Twitter, and build your own app that only the savviest user will notice is actually posting to Twitter as “Twitter for Mac.”

    Twitter’s willingness to exempt any apps from the OAuth procedure is a concession that they don’t view xAuth authentication as inherently insecure. But they want to limit which API keys get the privilege of continuing to use it. So, expand that list of API keys. At the very least, add long-time supporters such as Iconfactory’s Twitterrific. Better? Provide some kind of approval process through which any qualified developer can seek first-class status. Best of all? Stick to what OAuth and xAuth are best for: providing the power to revoke access for bad actors after bad intentions are discovered. Forcing applications through OAuth is not going to prevent offensive, buggy, or intentionally malevolent code from being authorized by users, but it is going to degrade the user experience for all native clients except, oh, how about that? Twitter’s own.

    Verdict: Dick move, Twitter.

Core Data Model Merging

May 4th, 2011

I haven’t used Apple’s Core Data framework all that much, but I’m trying to dabble more in it with newer projects where I don’t rely as much on legacy data storage, or am willing to take the hit of migrating from those legacy persistence models.

As a developer, the obvious upside to using Core Data is Apple’s powerful framework manages most of the nitty-gritty details of managing the … well, the data your app uses both in memory and on disk. But giving up precise control over the storage and mangement of this data also becomes maddening when you run into problems: you’re not directly responsible for the management, so you’re less likely to know exactly what is going wrong.

I ran into a problem recently having to do with versioning of core data model schemas, and how good a job the frameworks do or do not do of automatically updating existing data that a customer may have on disk. In recent years Apple has made it increasingly easy to make minor changes to your model schema and having the frameworks handle the migration easily. Apple calls this trivial technique lightweight migration, and when it works well, it works very well. To modify your existing data model, you just add a new “version” of your xcdatamodel file, and add a few options flags when creating your persistent store:

NSDictionary *options =
   [NSDictionary dictionaryWithObjectsAndKeys:
   [NSNumber numberWithBool:YES],
     NSMigratePersistentStoresAutomaticallyOption,
   [NSNumber numberWithBool:YES],
     NSInferMappingModelAutomaticallyOption, nil];

[myPSC addPersistentStoreWithType:NSSQLiteStoreType
   configuration:nil URL:storeUrl
   options:options error:&error];

This actually works quite well for simple addition or removal of entity attributes, but you might be forgiven for assuming its completely freaking broken if you run into a problem I did, having to do with a stale “.mom” file being left in the built application’s bundle in the iOS simulator and on iOS devices.

Essentially, if you’ve been building your project up to now with a single, unversioned xcdatamodel file, and you convert it to a versioned xcdatamodel file, it will start producing a new “.momd” file in your application bundle, and stop producing the older “.mom”. But because of a bug in the way Xcode installs the application binary in the simulator and devices, it will leave existing files from previous builds where they were in the bundle.

If, like many folks, you use the convenient [NSManagedObjectModel mergedModelFromBundles:nil] method to initialize your managed object model, this will, to use a technical term, bite you in the ass. The problem is Core Data looks at the .mom and the .momd files as equally viable, and attempts to merge them into some cohesive whole. When it discovers they both redundantly describe the same entities, it blows a gasket with a runtime error like “Can’t merge models with two different entities named ‘MyEntity'”

I did some googling around and discovered that the simplest solution is to simply delete the iOS app from the device or simulator, ensuring that the next time you install, you get a pristine, clean copy of the app without the troubling “.mom” file. But there’s a huge problem with that: in deleting the app you also delete its associated data files, and thus are left in a position where you aren’t actually testing the ability of Core Data to effectively migrate from your previously versioned data.

On the simulator, it’s no problem to dive in and trash the problematic, stale file. You can find the application binary somewhere in:

[Home] -> Library -> Application Support -> iTunes Simulator

Once you’ve deleted the “.mom” file you can test with your new model and everything hopefully works great.

On the device, it’s not as easy (I think) to get in there and do pinpoint editing of the application contents, but I still wanted to test my changes against the real data on my device. I was also starting to get paranoid about the possibility of an App Store update at some point also causing a stale “.mom” file to be left in an app bundle, and wreaking havoc. So the 100% safe solution to make sure the one-true “.momd” file is consulted when building the Core Data object model, is to point directly at it:

NSString *momdPath = [[NSBundle mainBundle] 
	pathForResource:@"MyModel" ofType:@"momd"];

NSURL *momdURL = [NSURL fileURLWithPath:momdPath];

managedObjectModel = [[NSManagedObjectModel alloc]
	initWithContentsOfURL:momdURL]; 

Hopefully seeding this solution into my blog will make it available for folks searching on similar failures in their Core Data projects.

MarsEdit 3.2.2

April 21st, 2011

MarsEdit 3.2.2, an extremely minimal update to 3.2.1, which nonetheless fixes some importantly frustrating bugs, has been rejected by Apple for alleged violations of their policies that I can’t yet make sense of. Rather than postpone indefinitely the availability of this release while I work out the issues with Apple, I’m making it available immediately to all customers.

MarsEdit 3.2.2

  • Fix an issue where the posts list is sorted in wrong order on launch
  • Fix Tumblr support to allow downloading more than 50 recent posts
  • Fix an issue where passwords were sometimes not accepted correctly with Blogger & Tumblr

I recommend that all direct-purchase customers update at your earliest convenience.

For Mac App Store customers, I recommend that you upgrade to the direct-download version only if you are eager to see fixes for any of the issues listed above. If you have run a Mac App Store release at least once on your Mac, the downloadable version of MarsEdit will run as a fully-unlocked version for you, but will not continue to be updated automatically by the Mac App Store.

I’m sorry for the confusion. I prefer to release updates of MarsEdit simultaneously to both App Store and direct-download customers, but in situations like this I feel it’s important to move on with life while continuing to work with Apple on the issues that are preventing approval.