Blog

Re: Apps that work together – on iPad

Posted: May 27, 2010 by Billy Gray Tagged iphone, programming, cocoa, touch, response

Brent Simmons lays out the case for setting up a sort of gentlemen’s agreement between iPhone OS developers, or at least an agreement in behavior for the apps – in order to facilitate inter-app communication. The title of his article refers to iPad, but the concept applies well to all iPhone OS apps, and he asks if his solution is sensible or silly:

But we don’t have an easy way to get back to the calling app. Imagine a hypothetical case like this:

  1. You’re in Twitterrific, looking at a web page, and there’s a link to a feed. You want to subscribe to that feed.
  2. So you choose a “Subscribe in NetNewsWire” command. It opens NetNewsWire and subscribes to the feed.
  3. Now that you’ve done that, you want to get back to your place in Twitterrific. You want it to be exactly as if it never quit.

We can do #1 and #2. It’s #3 that’s tricky.

So I have an idea. It just came to me, so I don’t know if it’s good or bad — but it’s worth posting, at least.

What if the calling app added, as a parameter to the URL, a URL to call when the task is completed?

Seems pretty sensible to me. It would be fantastic for Strip. I’ve been looking for ways to make our password manager more easily accessible from other apps so that it’s easy to take that very round-trip he describes into Strip and back out to another app to either store some data in Strip and go back, or to retrieve some data from Strip to use. It’s pretty easy now, but it could be better, it could just work.

I think Bret’s idea is a really good one, and provides for a lot of flexibility going forward. However, there’s still no way an app could “discover” what other apps are available and what services they provide under this scenario, and that’s really clutch for this sort of thing, for providing a button like “Fire a flame thrower in NetNewsWire” and knowing that it will in fact launch NetNewsWire and run some fictional “Fire a flame thrower” command.

Maybe apps should broadcast their services over Bonjour to the localhost? Right there we already have a very solid model for advertising and discovering “services,” although it doesn’t quite lend itself to application switching. And on iPhone OS 3 and lower, no application that isn’t running could advertise a service in the background.

In iPhone OS 4, that will no longer be the case, it would seem. Perhaps one could just run a bonjour advertisement for a service in the background in an NSOperationQueue? What an awful kludge that would be. I don’t understand why this isn’t a basic feature of iPhone OS 3 already.

New Website for Strip

Posted: May 26, 2010 by Billy Gray Tagged zetetic, website, strip, iphone

We’ve put a little bit of extra elbow grease into our web presence over the last couple of weeks, and as part of that effort, we launched a new website just for Strip last night: getstrip.com.

That gorgeous design is the work of Mr. Johnny Bilotta.

We expect this will serve customers of Strip quite a lot better than the old sub-page on zetetic.net, it makes it a lot easier to find information about the program itself, and there’s a ton of documentation on there. We’ve redirected/rewritten all old links to the new site, let us know if you see any broken ones. And let us know what you think!

Thanks to Johnny, Bret Morgan of DBL Systems who helped me hack out all the wiring, and the rest of the Zetetic Team (Don Quander, Steve Kradel, SJ-Lo) for doing such a great job and providing great feedback.

One of the nifty things about this site is that we decided to forgo any kind of webapp or content management system, and instead built a completely static site using HAML, SASS and staticmatic. We thought it worked out so well that we’re doing the same for zetetic.net at the moment, and moving off of Radiant. We had a good run with Radiant, but upgrades have been extremely painful and it’s really easy to break the site. We like kicking it in a text editor and using Git to manage our static content, much nicer than having it all in a database. As for the blog itself, we’re building ourselves a fresh Rails 3 app to hone our chops for upcoming upgrades.

Building SQLCipher with QT

Posted: May 26, 2010 by Billy Gray Tagged sqlcipher, tutorial, qt, igorbogomolov

Russian developer Igor Bogomolov put together a fantastic tutorial for building SQLCipher with QT in Russian, and it translates really quite well into English via Google Translate. That’s really quite remarkable.

Thanks again, Igor!

Updated: openssl-xcode and billymeltdown-choctop

Posted: May 20, 2010 by Billy Gray Tagged

Stephen has updated the openssl-xcode project to support building OpenSSL 1.0.0. We’re not entirely sure why, but the make process was attempting to use x86 assembler on non-x86 architectures (ppc, armv6, etc), so we updated the build script in the Xcode project to do the right thing by setting certain flags based on architectures. Works like a charm, now.

This was tested with Xcode 3.2 and OpenSSL 1.1.0 only, results may vary with different versions of either. You can grab the latest by pulling from the master branch.

I’ve updated our fork of the fantastic choctop Ruby gem, which we use to automate release builds for Mac OS X apps. The recent change adds a “codesign_identity” accessor. Set this to the name of your code signing identity and the gem will sign the target app bundle right before it builds the DMG. My fork can be found and forked here on Github, but to install you can pull it from Gemcutter, the name of the gem is billymeltdown-choctop, e.g.:

gem install billymeltdown-choctop

Then you can require it in your Rakefile like so:

gem 'billymeltdown-choctop'
require "choctop"

Example Rakefile:

ChocTop.new do |s|
  s.build_opts  = '-sdk macosx10.5'
  s.codesign_identity = 'Zetetic LLC'
  s.remote_dir  = '/www/zetetic.net/current/public/files/strip-sync'
  s.base_url    = "http://www.zetetic.net/files/strip-sync"
  s.build_products  = "/Users/wgray/Documents/Sources/xcode-build/Release"
  s.transport   = :rsync
  s.rsync_args  = '-vazxS --delete -e "/usr/bin/ssh -p 11122" '
  # ...
end

My fork has been modified from the original in numerous small ways because I had to get it working on OS X 10.5, and then 10.6. Caveat emptor.

Pretty Page Title in Rails 3

Posted: May 18, 2010 by Billy Gray Tagged rails, ruby, tricks, railscasts

Ryan Bates has an incredible video tutorial series called Railscasts. They’re really fantastic, and the recent ones focusing on Rails 3 development are invaluable to someone like me who’s playing catch-up, having been in iPhone SDK land for what seems like the last six months.

In any event, he posted this nice trick a while back, called Pretty Page Title. You can watch the railscast for all the details, but the basics of it are a means to set a default bit of content in your layout, and override it from a particular page view. The most obvious example is the HTML title element, but we also need it for things like page description, keywords, other meta content. Here’s what the code looks like:


# application_helper.rb
def title(page_title)
  content_for(:title) { page_title }
end

<!-- layouts/application.rhtml -->
<title>Shoppery - <%= yield(:title) || "The Place to Buy Stuff" %></title>

The crux of the trick is the || operator. If yield returns some value evaluating to false (such as nil), “The Place to Buy Stuff” becomes the content. This is important because it means in a particular view page file, you could over-ride this. Pretty handy for product pages or individual blog posts!


<!-- show.html.haml -->
- page_title(@article.title)
= render @article

This trick no longer works, because content_for returns a blank string when no content has been supplied. I’m not sure when it stopped returning nil, but that’s the case, and I suspect it’s a Rails 3 thing.

In the spirit of giving back (and because I needed it), I hacked up an alternative that’s working pretty nicely for us on a new project (replacing our blog in Radiant with a custom Rails 3 blog). The idea is to check content_for for any content in a helper method and return default content if it’s blank. Here it is as a Github gist, hopefully this loads nicely:

This works because content_for acts as a kind of accessor (both get and set) for the content you pass to it. No need for yield! Which is good, because if you try to call yield inside the helper method, you’ll be treated to the actual Ruby yield, which won’t look kindly on your symbol ;-)

SQLCipher Performance and SQLCipherSpeed

Posted: May 07, 2010 by Billy Gray Tagged sqlcipher

Recently, we had a query on the the SQLCipher Users’ mailing list inquiring about the performance of a LIKE query, where the user was wondering if SQLCipher’s encryption engine was responsible for poor performance he was seeing in his code. “It depends,” is the cheapest and most accurate answer we could give without seeing his query and the EXPLAIN plan generated by SQLite (no index, for instance, could lead to a full table scan, thus requiring every page to be decrypted). What we do know is that performance of SQLCipher compared to SQLite is really pretty good, and certainly good enough for our needs as application developers.

If you’ve been wondering what kind of performance hit you can expect using SQLCipher as compared to vanilla-SQLite, we’ve published a new tool to help you get an idea. In the end, EXPLAIN and EXPLAIN QUERY PLAN cannot be replaced, but for a quick side-by-side reference to see that we’ve done a half-decent job, check out Stephen’s SQLCipherSpeed. It’s an iPhone OS project that rips through the various SQLite speed tests. I ran it on my crunky iPhone 3G and the results were about what I expected, and pretty interesting:

In this next one, note that there is no performance impact for 2500 selects on an index.

You’re highly encourage to check out the code yourself, and to fork it. It would be really cool if someone added an action button to the results screen to email the data off-device. More tests wouldn’t hurt either.

Strip Sync beta Update / Strip v1.4

Posted: May 07, 2010 by Billy Gray Tagged strip, stripsync, beta, update, export, import, data, workflow

The beta test is moving along pretty nicely. If you haven’t been sent any files or updates just yet, but you’ve already opted to participate, don’t worry, we’ll hook you up soon! At the moment we’ve got a loose target date of June 1st for general release, although we don’t really know exactly how long it will take for the newest version of Strip to appear in the App Store after we submit it.

The most recent update to Strip Sync is that we’re now supporting bulk updating of existing Entries during the CSV Import process. Simply use the Export feature to dump out a CSV of all your entries, and you’ll see a new column called “EntryID”. This contains what is basically a GUID for each entry, and if you include these rows in an import, the data in the row will cause the entry to be updated. Original CSV spec post has been updated to reflect this.

We’ve also made numerous improvements to the display, work-flow, responsiveness, and memory usage of Strip running on iPhone OS. Even if you don’t want the new Sync features, the improved layout of field labels and data values is so much better, and much easier to read. We’ve finally added a much easier to utilize Copy function for each field on display (no need to drop into edit mode anymore just to copy a password), and similarly for launching applications with a particular piece of data stored in Strip, and this really makes the program a lot easier to use for everyday look-ups.

For instance, you might want to log into your insurance website account. You open up the insurance entry, you see the password row, you just tap it, and a Copy menu comes up, allowing you to copy the password to the system’s “Pasteboard:”

From here, you just want to go to the website so you can use that password:

And if you’re a sysadmin, with perhaps Touch Term installed on your iPhone or iPad (or some other SSH terminal program), you can just use the ssh:// URL scheme (or any other URL scheme) to do your thing. Here’s a similar scenario, involving some system credentials:

Copy the password for use in the next program:

Now fire up an SSH application:

And the password textfield in this other app (not Strip) allows us to paste the secret password from our clipboard.

An ironic twist: something I did in the most recent beta build of Strip causes this to dial the Phone instead of launching the SSH app, will have a fixed build out early next week, I expect.