on Withings Activité

I am looking forward to develop for the Apple Watch and i am really looking forward to using it to monitor my pulse when doing sports but i do not think i want to wear such a bulky watch on my hand at all times.

Enter the Withings Activité, lovingly crafted in Le Locle village of the Watch Valley it is a rather impressive marriage of the traditional mechanical watchmaking and the latest motion sensors talking to your phone via bluetooth 4.0 on a single battery change a year (as opposed to one day for the Apple Watch).

But the charging frequency is not the only big differentiator between Apple’s wearable and the 37g Activité , there will likely be quite a size and weight difference as well so i went ahead and preordered it for it’s nimbleness and craftsmanship but i was not expecting the big impact of the mechanical component.

When you first set it up you calibrate the clock hands with your finger on the phone as you hear the clock gears churn and turn obediently, it is almost magical and just makes you think and appreciate even more those tiny mechanical wheels and the work that went into them, the combination of the old and new just clicks.

I have been wearing a Jawbone UP just short of two years now and even if overall i found it a good activity tracker i am quite looking forward to part ways with it largely on account of it’s bloated software, the food entering user experience is daunting and there just is no explanation as to why it still vibrates to remind you to go to sleep even if you are already sleeping (sometimes waking you up) the opposite with the wakeup alarm also happens to less aggravating extent.

Now overall the Jawbone UP sensor readings seem a bit more polished and it does not log you as sleeping if you wear the watch on the hand you mouse with and just click away for some hours, neither does it try to guess (and likely fail) if your activity was a run or a walk, it is a more mature product than the Activité (which has not even had it’s retail launch yet).

That being said, mature as it is the Jawbone UP is after all just a plastic band and if the battery does not die after a few years the thing itself will definitely fall apart eventually, compare that with a swiss made timepiece that is likely to outlast your lifespan at just twice the price and one starts to get the feeling the UP is just not worth it.Nike+

Before parting ways with the UP i wore it alongside the Activité to do some comparative testing of the readings, here is a run as recorded with Nike+ Running, it uses GPS to calculate the exact distance so it should accurate enough to use as a control, it puts it at 4.7km over 30 min (excluding 10 min of breaks) and 385 calories.

The Withings app registers this 40 min activity as a 3.7 km walk using 136 calories, the Jawbone app asks you to fill in the type of activity and puts it at 4 km and 494 calories.

This is quite a discrepancy between the readings, all three apps know my height and weight, granted Withings thinks it is a walk therefore the lowest calorie estimate, but Jawbone seems to overestimate quite a bit as well so the jury is out, at least Withings has the benefit of not being quite so mature.

withings runwithings dayjawbone runjawbone day

Next up, sleep, again Withings has to guess on it’s own so it records 2 instances at 2am and 2pm as sleep when i was actually at the computer which is a shame since the next day when Withings seemed to have better sleep tracking accuracy, it correctly detected that i only woke up 2 times and slept 6 and a half hours, Jawbone seems to be a bit off with waking up 6 times all trough the night and maybe overestimating the deep sleep.

withings sleeptithings sleep todayjawbone sleepjawbone sleep today

Word by word

In which i analyze a paragraph much loaded and far reaching, from http://arstechnica.com/tech-policy/2012/12/victory-for-the-tabloids-online-porn-to-be-filtered-by-default-in-uk/ word by word to determine it’s implications, applicability, effectiveness and eventually it’s uttermost impossibility.

The paragraph is “Every owner of a new computer will be asked when they log in through their Internet service provider if they have children in the house. If they answer yes, it will immediately prompt them to set up filters blocking content, individual sites, or restricting access at particular times of day”

#1 – “Every owner” : requires technical ability to identify the “owner”, computers do not typically come with biometric identification peripherals nor can ISP’s be imagined to hold a database linking such biometrics to a given person.

Verdict: improbable technically, privacy implications, ISP cost implications, can’t really be enforced.

#2 – “a new” : requires technical ability to determine it, the network hardware’s MAC address can be used for that but it implies the ISP storing a database of all MAC addresses in order to determine if the machine is “new”, a guest’s computer would have to go trough the same activation/identification procedure in order to have internet access.

Verdict: possible technically, privacy implications, ISP cost implications, locks internet access to the owner’s computers, improbable to be enforced.

#3 – “computer” : requires technical ability to determine if a networked hardware connecting to the ISP is a “computer” or some other kind of internet connected device like say a Nest thermostat, advanced heuristics can be employed if extensive traffic analysis is performed as to see what kind of internet services are being accessed.

Verdict: can’t be accurately determined technically (only guessed) , privacy implications, ISP cost implications, can’t really be enforced.

#4 – “will be asked” : requires a interface between the ISP and the computer user, there are only two ways, ISP’s software has to run on the computer (very hard if it is a iPad for example) or a browser based approach has to be taken, for the browser approach a browser must be opened, if the user never opens a browser it would be technically possible to access the blocked content from other applications without the browser ever getting a chance “to ask” unless everything is blocked by default for any new (unknown) device and each has to be activated/identified (see #2).

Verdict: can’t be universally applied technically, ISP cost implications, hard to be enforced.

#5 – “when they log in” : requires a log in between the ISP and the computer user which has to be either implemented in the operating system, ISP’s software has to run on the computer (see #2) or done trough a browser,

Verdict: can’t be universally applied technically or it limits the types of compatible “computers”, can’t be enforced without ISP loss in market/service availability.

#6 – “through their Internet service provider” : what if it’s not their ISP and they are just guests at the owner’s house, being able to share your internet connection with guests might not be an inviolable human right but it’s something taken for granted and people will easily notice if it goes away.

Verdict: can’t be enforced without taking exiting functionality and/or PR backlash from public uproar.

#7 – “if they have children in the house” : assuming this means “if they have children” period, as in your legal children, not if say children come to visit your house it still boils down to your declaration as such, the ISP does not have a database to the customer’s children (even if it could get access to entities that do)

Verdict: comes down to a person’s declaration, ISP cost implications if they have to access a third party’s database to determine this.

#8 – “If they answer yes” : What if that is now known, sure everyone knows if he has children or not right, well how about the cases when they don’t know, or when they don’t have today but will have tomorrow.

Verdict: can’t be determined absolutely, only for a very specific point in time, assumes knowledge of the fact and the respondent not lying.

#9 – “it will immediately prompt them to set up filters blocking content” : Yea, people are very good on setting up filters and managing them, and ISP’s are very good at making effective interfaces for doing so.

Verdict: ISP cost implications, usability implications.

#10 – “content” ISP has to monitor traffic for content.

Verdict: impossible with encryption, privacy implications, ISP cost implications, can be marginally enforced.

#11 – “individual sites” ISP has to monitor DNS requests to determine sites or monitor and resolve IP’s in HTTP requests to domain names (in a timely manner without creating lag for the user), if a DNS server like Google’s “Public DNS” or OpenDNS is used the ISP has to fall back to monitoring and resolution of the traffic itself or mandate usage of ISP’s DNS.

Verdict: hard if ISP’s DNS is not used, privacy implications, high ISP cost implications, can be marginally enforced.

#12 – “restricting access at particular times of day” : no impediments, the only sensible thing of the whole bunch

Verdict: totally doable.

You might have notice three things that come up, first there are cost implications for all points, secondly technical issues for almost all and privacy implications for many, in the order of your choosing these are pretty heavy bottlenecks, even if i am wrong in 90% of my assessments there is still enough to make the enforcement of this impossible or limiting it’s scope just to #12.

Three truths of software revisions

I am no expert in user experience, probably not even in software design, but over the over the course of more than a decade using and writing software i have come to impart several truths, i will go on dispensing these things i consider as such.


But first off i need wax philosophically on the concept of revision itself, feel free to skip ahead to jump to the meat of it if you are so inclined.

So what are revisions, what do they imply, and why are they important ?

Revisions are not exactly a new concept, as with al things we can take a look at nature for immediate analogues, i trust you will be able to find plenty in a glance, they are new however for some things.

As time goes by some familiar concepts, like the books in your network connected e-reader, gain revisions they become a living entity, others like a De Lorean DMC-12 get frozen in time, forever still (or not).

And what do revisions imply ? well they imply evolution for one and a lifeline for a close second.

Something that has revisions can almost feel as living and breathing and is very different from the coldness and perfection of master’s ancient greek sculpture (very different and very similar if you will see the sculpted figure as alive).

As to why are they are important, just thinking about your opposable thumb the next time you grab something with your hand should suffice.


Now on to the truths i threatened with, i assume there are books that feature them, not that i read any, but i digress, software revisions colloquially called “updates” are a mighty important concept and they need to hold true to some values.
As all truths, these specific ones on software updates might apply to some extent to all software at large, some might sound like common sense, if they do please let me know which ones.

  • Truth one: what once was given should not be easily taken, even if it was wrong, a good update takes this into account above all and in treats the rare cases where something just has to be taken with extreme care.

This is probably the most controversial of the bunch and can be argued pro and against to no end, battle scarred developers know which ones weight more, as far as i am concerned as true as i even known truth to be.

  • Truth two: a good update is discreet, noninvasive, it does not hit you in the head, does not scream change, one might even find himself wondering if the update existed at all, only very few things are needed to denote new, if any.

This is probably less controversial, if you want to hit people in the head you should seek professional treatment, i am just going to state it as a truth because it is.

  • Truth three: a good update has a continuum, most changes in it have a segue to a previous concept, very few, if no changes stand on their own coming out of thin air.

You know this one to be true yourself, i don’t even have to argue it, if you wake up one morning with one extra limb that you have no idea how to operate i just don’t see how you’ll appreciate it.


That’s it for now, i never claimed to have all truths about software updates, any constructive commentary is one of the reasons for writing this, so please do.

The way i see it the future is all software, the survival or demise of humanity might as well hang on it, we cant just bang rocks together hoping for the best.

So please do the world a favor, if you are going to change something so much in a revision that it barely resembles it’s predecessor make it a new thing, not a revision, rethink it from the ground up and let the original turn cold and perfect like a ancient greek sculpture.

how to turn your old Palm Pre into a skypephone

I keep a old Palm Pre 2 around for historical reference, WebOS was a nicely designed operating system and i like to dust it off every once in a while but other than that it is pretty much a museum piece.

However in webOS 2.2.4 HP added Skype support so i figured id make the Pre into a skypephone and document the process, it should be as easy as pressing update on the phone to get the 64 mb 2.2.4 OTA but that does not usually work so here we go the manual way of restoring  a clean 2.2.4 image directly to the phone (lines in italic are terminal commands)

You can skip STEP 4 if you have a sim card nearby to put in the phone and want to make or use a existing webOS account (STEP 4 will lock your webOS account to a generic Dr. Skipped Firstuse account)

STEP 1 (downloads)

download http://vladalexa.com/wpcontent/2012/08/webos_devicetool_and_novacom.zip (and/or extract) to your desktop
download the webosDoctor for your device withe the WebOS version you prefer from  http://www.webos-internals.org/wiki/WebOS_Doctor_Versions (get WebOS 2.2.4 which has Skype support  webosdoctorp224pre2wr.jar in my case)

STEP 2 (driver)

move ~/Desktop/NovacomInstaller.pkg to /Library/Receipts/NovacomInstaller.pkg

sudo ~/vlad/Desktop/novacom/novacomd

STEP 3 (webOS)

right-click Open on webosdoctor******.jar
follow the procedure to install the os

STEP 4 (activation)

connect the phone to the mac's usb port
turn off the phone then back on again while holding volume up until the usb logo shows

java -jar ~/devicetool.jar

STEP 5 (skype)

enable Wi-fi (unless you activated a sim card with a data plan)
open contacts, press "Add An Account", select Skype


What else can you do with this phone ? If it hasn’t stopped already the HP App Catalog will eventually stop working, you can get Preware a homebrew app store.

Skype video call option is available but don’t expect it to work, overall skype seems to work good enough on webos tho at one time it just would not connect.

The devicetool.jar downloadable here contains the all three images for most palm 2 phones unlike the official hp download:

Four things Apple needs to fix

1– Add iCloud versions/Time Machine or some other way of backup, once people migrate their data to iCloud traditional backup methods become impossible or at least highly impractical, add to that the ability to delete files from any device and the lack of backup starts to show all the signs of a usability nightmare.

I do not expect the majority of people to bump into this until they are deep into relying on iCloud for storage in the years to come, but they eventually will and
Apple should have something ready as soon as possible.

2– Fix iTunes (including AppStore, iBooks store etc) discovery and search, it is pretty much broken at the moment as plain text searches yield hundreds of results with irrelevant sorting by download counts.

Having so many featured and suggested categories is a weak solution and it makes no sense since it copies the model of the entertainment business which works totally different from that of software, it is no use to have billion apps in the store when the actual 0.1 of the apps get 99% of the users (just a illustrative estimation, not factually accurate)

It looks like they just copied their music store model piecemeal without giving it a second thought, and it should be pretty clear by now that a  custom approach is needed for the app stores, a good model to emulate would be Netflix, the way it works to highlight new or relevant movies to you, not just push the already hyped and popular blockbusters down your throat.

3– Fix AppleTV by adding the “passive” mode to every stream eg: shuffle for Music, play top Podcasts, play my Vimeo Feed, that is analogous to legacy TV behavior where we quickly select a passive stream (TV channel) with minimal effort, this has to be available in every content module in AppleTV, accessible with preferably a single user interface interaction/dedicated remote button

Preferably it should also be smart and pick content based the user is statistically probable to like, not just push the most popular content (see #2 above)

4– Fix OS X for the post-pc era by removing it’s features that were added specifically for the kind of audience that migrated to iOS devices.
Consciously and explicitly switch to a paradigm where they consider the users for OS X professional tech-savy users as opposed to the iOS users and start to design software accordingly, specifically adding more finesse to OS X and make it tend to the professional and technology savvy.

We have seen signs of this with the revival of Dock support for symlinks, Finder folder merge etc, but this should be made into a explicit direction for OS X in order to focus it on the post-pc users that are not merely using it for web browsing and content consumption.

With MountainLion they pretty much achieved the needed synergy between their two OS’es, from now on it is time to play on each individual one’s strengths.

basics of iOS and OS X API’s

The structure of OS X and iOS native* API’s is very straight forward/minimalistic, typically one does not need to know about anything that goes below the Foundation API however taking a look at the headers can help understanding it better and clearing common confusions between Foundation and CoreFoundation or what exactly constitutes CocoaTouch and Cocoa since the later is a explicit framework while the former is just a naming convention.

All the API’s are present as binary frameworks under /System/Library/Frameworks (with resources but without headers) and under your Xcode toolchain SDK (with headers but without resources) , the objc binary is at /usr/lib/libobjc.A.dylib while the headers are under /usr/include/objc/ and your Xcode toolchain.

Now let’s dig right into it, at the lowest level there is CoreFoundation and objc, they are independent of each other :

objc_class,objc_object,objc_selector etc

objc_getClass,objc_getProtocol,class_conformsToProtocol etc

super_class,objc_super,objc_msgSend,objc_msgSendSuper etc

(you can include all the above with #import <objc/objc-class.h>)

CFString,CFNumber,CFArray,CFRunLoop,CFStream etc (this is just C, there is no Objective-C syntax or anything at this level)

On top of these and including (relying on both) is Foundation, as the name implies you typically never use any API’s below foundation directly.

NSString,NSNumber,NSArray,NSRunLoop,NSStream etc, much of it is toll-free bridged to CoreFoundation

on top of Foundation there is AppKit for OS X or UIKit for iOS
(on OS X you typically include Foundation, AppKit and CoreData with #import <Cocoa/Cocoa.h>, there is no corresponding CocoaTouch shell framework on iOS)

NSView,NSButton,NSColor,NSEvent etc

UIView,UIButton,UIColor,UIEvent etc

This is pretty much all there is, from this on there are multiple optional frameworks you can use for specific cases, but the basics are just in the headers above, most API’s are Cocoa but there is still a big chunk of C API’s especially on the OS X side.

It’s worth nothing that there are two types of frameworks : private and public , the private ones are not safe to be used and not allowed in the Mac App Store , the public ones are safe to be used as long as they have headers in the SDK (they could be present in /System/Library/Frameworks but not in the SDK) typically such disparity is a rare occasion nowadays and it was more common prior to 10.6.

One more note is that public frameworks with headers might not have all their methods/classes documented, nevertheless using them should be pretty safe but the lack of documentation is a indication that they are more likely to change/go away than the documented ones.

*OS X and IOS also have the low level BSD API’s (found in /usr/include) most of which are cross-platform and outside the scope of this post.

extended attributes, spotlight and xcode screenshots

If you shall find yourself wondering, as i did, how exactly does Xcode know which device too what screenshot from the ones it manages the answer is simple, it just saves extended attributes for the files with the device id under com.apple.DTDeviceKit.screenshot.device_id e.g.

[valexa@VAiMac:~] $ xattr -l /Volumes/Storage/Screenshots/Screenshot 2010.07.13 01.43.57.png
com.apple.DTDeviceKit.screenshot.device_id: 5a14571ebe34512345b7345e13454a

Finder being finder has no way whatsoever to display or search for extended attributes, however some useful spotlight metadata is saved (the spotlight metadata itself used to be saved as extended com.apple.metadata attributes and xattr is still the only way to edit it) :

[valexa@VAiMac:~] $ mdls /Volumes/Storage/Screenshots/Screenshot 2010.07.13 01.43.57.png
kMDItemPixelHeight = 1024
kMDItemPixelWidth = 768

This can in fact be searched with finder even if not readily apparent, you have to add a specific Raw Query for it to understand the raw commands that you would have given to mdfind e.g.:

[valexa@VAiMac:~] $ mdfind -onlyin /Volumes/Backup kMDItemIsScreenCapture == 1
/Volumes/Backup/10.8/Screen Shot 2012-03-03 at 12.00.30 AM.png

This searches for screenshots taken from your mac (you can search for specific types for example whole screen ones with kMDItemScreenCaptureType == “display”, screenshots taken of specific windows with kMDItemScreenCaptureType == “window” or “selection” etc)

I had to do this because my screenshots folder contains both the Xcode ones and my mac screenshots, my specific goal was to figure out why some iOS screenshots there no longer showed under their corresponding devices, it turns out that i edited some with Photoshop and it replaced the extended attributes.

Editing those attributes with finder and AppleScript while possible is extremely convulted and employs shell calls anyway so we just head back to Terminal with the newfound knowledge of what screenshots we have.

Now if you only have one device for each screen resolutions available in iOS you are in luck, to print the extended attributes for iPhone, iPhone Retina, iPad, iPad Retina respectively, you can do:

mdfind -onlyin /Volumes/Storage/Screenshots/ “kMDItemPixelWidth == 480 || kMDItemPixelHeight == 480” -0 | xargs -0 xattr -l
mdfind -onlyin /Volumes/Storage/Screenshots/ “kMDItemPixelWidth == 960 || kMDItemPixelHeight == 960” -0 | xargs -0 xattr -l
mdfind -onlyin /Volumes/Storage/Screenshots/ “kMDItemPixelWidth == 768 || kMDItemPixelHeight == 768” -0 | xargs -0 xattr -l
mdfind -onlyin /Volumes/Storage/Screenshots/ “kMDItemPixelWidth == 1536 || kMDItemPixelHeight == 1536” -0 | xargs -0 xattr -l

Now that you seen your device id’s of the screenshots with proper attributes you can go ahead an set the proper id for all screenshots for a screen type e.g.:

mdfind -onlyin /Volumes/Storage/Screenshots/ “kMDItemPixelWidth == 480 || kMDItemPixelHeight == 480” -0 | xargs -0 xattr -w com.apple.DTDeviceKit.screenshot.device_id ‘5a14571ebe34512345b7345e13454a’

Xcode will immediately catch on the change and credit the screenshot properly for it’s source device.

refresher on resource forks

Resource forks are a strange beast, while Apple started moving away from them (around 10.4) and migrated to HFS Attributes, software like Adobe’s Photoshop still save (can be disabled in Preferences > File Handling) file previews as resource forks, here is a refresher on how to view, find and delete resource forks.

You can see is a file has a resource fork in a number of ways (they all involve the terminal)

1- see if the file has a “com.apple.ResourceFork” extended attribute

xattr /Volumes/Volumename/Dirname/filename.extension

2- lookup the attributes of the resource fork directly

ls -l@ /Volumes/Volumename/Dirname/filename.extension

ls -ila /Volumes/Volumename/Dirname/filename.extension/..namedfork/rsrc

File system operations can be performed on a resource fork just like any other file so you can copy or delete them, to get a path to the resource fork you add /..namedfork/rsrc to the full path of the file in question, for example to copy then remove the fork:

cp /Volumes/Volumename/Dirname/filename.extension/..namedfork/rsrc ~/Desktop/thefork.rsrc

rm /Volumes/Volumename/Dirname/filename.extension/..namedfork/rsrc

You can also delete the fork by removing the extended attribute

xattr -d com.apple.ResourceFork /Volumes/Volumename/Dirname/filename.extension

Or print a hex dump of the actual data in the fork

xattr -l com.apple.ResourceFork /Volumes/Volumename/Dirname/filename.extension

You can find all the files that have resource forks with this terminal command :

find / -type f -exec test -s {}/..namedfork/rsrc ; -print

Now if you were to combine the last two you could delete all resource forks (in a given type of files under a certain path) e.g.:

find /Volumes/Volumename/Dirname -type f -name “*.extension” -exec test -s {}/..namedfork/rsrc ; -print0 | xargs -0 xattr -d com.apple.ResourceFork


Messing around with/deleting resource forks should be pretty safe nowadays, they were the mechanism used in Snow Leopard for storing HFS compressed files but this has been removed altogether in Lion.

The actual file as we know it is referred to as the data fork in this context and there used to be a way to get to it with /..namedfork/data but that does not appear to work anymore, if anyone can clarify please comment.

If you want to really dig into the gory details of your filesystem or maybe are in the unfortunate predicament of having to recover lost data i strongly recommend fileXray by Amit Singh, writer of the Mac OS X Internals book.

getting positive software feedback

It has been proven that the drive to give feedback on something is strongly polarized, that is the feedback is shaped by strong feelings either positive or negative, which makes sense, the people with median feelings do not care enough to give feedback, it should come as no surprise that this mechanic is relevant to getting positive feedback, basically to get positive feedback you want engagement, for people to care enough to say something, once you have that positive feedback is a given.

Negative feedback is inevitable, a user’s hardware or operating system could be defective, tampered by factors like jailbreaking/hacking or the feedback could be plain untruthful by either confusion or spambots/competitor malevolence, either way there will always be some, you might as well accept it.

However that inherent negative feedback is limited in scale, positive feedback can easily outpace it if there is any drive for the users to feel the need to express anything positive, what you want to do is instill that drive for positive feedback, those that have median feelings will not engage at all, it is only the poles of the spectrum that will generally be the source of most feedback.

Unless you have a serious problem that causes significant feedback all negative, just a little engagement to outweigh that inherent negative feedback will always tip the scale towards positive, with no engagement that little negative feedback is all you get.

Sandboxing woes

It’s a brave new sandboxing world they say and that brings about many implications good and bad, to a security professional asking the user for permission to read every single file might be pure heaven, to a UX professional it might be hell.

Either way consider this scenario, you have a application that needs to know some operating system setting, some configuration context, Apple can never provide exhaustive API’s for all scenarios and you will inevitably have to read or write to files the user does not directly need to interact with.

Before sandboxing you could just do this transparently, this is all good unless a attacker takes over your application and leverages it to wreak havoc, that is what sandboxing prevents but it also prevents legitimate scenarios and until Apple adds a way to specify in the entitlements a list of files that the application transparently needs to access the only way is to ask the user explicit permission.

Here is a way :

    //only needed if we are in 10.7
    if (floor(NSAppKitVersionNumber) < = 1038) return;
    //only needed if we do not allready have permisions to the file
    if ([[NSFileManager defaultManager] isReadableFileAtPath:file] == YES) return;
    //make sure we have a expanded path
    file = [file stringByResolvingSymlinksInPath];
    NSString *message = [NSString stringWithFormat:@"Sandbox requires user permision to read %@",[file lastPathComponent]];

    NSOpenPanel *openDlg = [NSOpenPanel openPanel];
    [openDlg setPrompt:@"Allow in Sandbox"];
    [openDlg setTitle:message];
    [openDlg setShowsHiddenFiles:NO];
    [openDlg setTreatsFilePackagesAsDirectories:YES];
    [openDlg setDirectoryURL:[NSURL URLWithString:file]];
	[openDlg setCanChooseFiles:YES];
	[openDlg setCanChooseDirectories:NO];
	[openDlg setAllowsMultipleSelection:NO];
	if ([openDlg runModal] == NSOKButton){
        NSURL *selection = [[openDlg URLs] objectAtIndex:0];
        if ([[[selection path] stringByResolvingSymlinksInPath] isEqualToString:file]) {
            [[NSAlert alertWithMessageText:@"Wrong file was selected." defaultButton:@"Try Again" alternateButton:nil otherButton:nil informativeTextWithFormat:message] runModal];
            [self punchHoleInSandboxForFile:file];
        [[NSAlert alertWithMessageText:@"Was denied access to required files." defaultButton:@"Carry On" alternateButton:nil otherButton:nil informativeTextWithFormat:@"This software can not provide it's full functionality without access to certain files."] runModal];

You need to add a call to punchHoleInSandboxForFile before every file access call eg:

[self punchHoleInSandboxForFile:@"/etc/hostconfig"];
NSString *stuff = [[NSString alloc] initWithContentsOfFile:@"/etc/hostconfig"];

This nags the user once for each file, once the hole has been punched for that file it persists for the lifetime of the process, it presents a file dialog with the file in question already selected (however that does not seem to be consistent, sometimes selecting the file will be required) .

Here’s hoping Apple adds something along the lines of setting specific files with permissions in the entitlements sooner than later, until then feel free to use this and suggest any better alternatives you can find.