Espionage 2.8.11 Released!

Espionage 2.8.11 provides Lion compatibility and other enhancements and fixes:

  • NEW: Lion support (now fully 64-bit!)
  • NEW: Complete extended attributes support for the encrypted folder itself (xattrs on files inside the folder were always supported)
  • NEW: Bitcoin application template
  • IMPROVED: Custom folder icon support
  • IMPROVED: Prevent unlocked folders from being backed up to ensure backup integrity
  • IMPROVED: Updated documentation and added example with link to blog instructions for Microsoft Outlook
  • FIXED: Espionage won’t complain if run from an external disk (or separate partition)
  • FIXED: Helper failed to run if home folder is located on non-root drive (e.g. /Volumes/etc..)
  • FIXED: Problems encrypting iPhoto Library
  • FIXED: “Don’t have a record for it” messages wouldn’t go away (hopefully for real this time)
  • FIXED: Alignment of master password field with written text above it
  • FIXED: On folder restore, sparsebundles were incorrectly sent to the trash with a sparseimage file extension
Lion Support

It is recommended to update Espionage prior to upgrading to Lion. If you were not able to do this, no sweat, simply download a fresh copy from our website and replace your copy of Espionage with it.

Full Extended Attributes support

Extended attributes are pieces of data that can be attached to files and folders (metadata in a sense). Some applications on OS X use them for various purposes, like indicating that a folder should be displayed as a bundle in the Finder (iPhoto does this). Espionage now fully supports them on the encrypted folders themselves (extended attributes on files and folders *within* the encrypted folder have always been supported).

Enjoy! :-D

Better Objective-C through Clojure Philosophy

Ever since discovering Lisp, I’ve felt an almost… loathing for other languages. They make things too complicated. You feel that other languages encourage code that ends up ugly, verbose.. inelegant. This feeling is so well known, it even has a name, the “The Lisp Snob“. Well, I’m quite sorry, but I think it’s too late for me, I’ve succumbed to the snobbery!

It’s possible, however, to bring over some of the ideas from the Land of Lisp to other languages. Indeed this is essentially what has been happening for the past several decades, people just call it something different (“a new language”, or “new features”). Today, I’d like to show what happens when you bring one such idea to Objective-C:

It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.

—Alan Perlis

PXSourceList is a wonderful and popular Cocoa view for creating iTunes-like source lists created by Alex Rozanski:

Unfortunately, the example code that created the screenshot above suffers from a very common programming paradigm called Object Oriented Programming (OOP). The OOP paradigm has dominated Earth’s developers for the past several decades. I used to follow (and teach!) it, but after learning Clojure, I’ve changed my mind. I now agree with the Alex Rozanski quote above and Rich Hickey: it is better to have a small number of core data structures (preferably immutable) that are manipulated by hundreds of functions.

For this post, I will focus on just one of the many benefits of dropping the OOP perspective: code brevity.

The chief source responsible for the screenshot above is copied below. My point here isn’t to ask you to actually read through all of it, just note its size.

Instead of this:

// =========================
// = File SourceListItem.h =
// =========================

#import <Cocoa/Cocoa.h>

@interface SourceListItem : NSObject {
    NSString *title;
    NSString *identifier;
    NSImage *icon;
    NSInteger badgeValue;
    
    NSArray *children;
}

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, retain) NSImage *icon;
@property NSInteger badgeValue;

@property (nonatomic, copy) NSArray *children;

//Convenience methods
+ (id)itemWithTitle:(NSString*)aTitle identifier:(NSString*)anIdentifier;
+ (id)itemWithTitle:(NSString*)aTitle identifier:(NSString*)anIdentifier icon:(NSImage*)anIcon;


- (BOOL)hasBadge;
- (BOOL)hasChildren;
- (BOOL)hasIcon;

@end

// =========================
// = File SourceListItem.m =
// =========================

#import "SourceListItem.h"

@implementation SourceListItem

@synthesize title;
@synthesize identifier;
@synthesize icon;
@synthesize badgeValue;
@synthesize children;

#pragma mark -
#pragma mark Init/Dealloc/Finalize

- (id)init
{
    if(self=[super init])
    {
        badgeValue = -1;    //We don't want a badge value by default
    }
    
    return self;
}


+ (id)itemWithTitle:(NSString*)aTitle identifier:(NSString*)anIdentifier
{   
    SourceListItem *item = [SourceListItem itemWithTitle:aTitle identifier:anIdentifier icon:nil];
    
    return item;
}


+ (id)itemWithTitle:(NSString*)aTitle identifier:(NSString*)anIdentifier icon:(NSImage*)anIcon
{
    SourceListItem *item = [[[SourceListItem alloc] init] autorelease];
    
    [item setTitle:aTitle];
    [item setIdentifier:anIdentifier];
    [item setIcon:anIcon];
    
    return item;
}

- (void)dealloc
{
    [title release];
    [identifier release];
    [icon release];
    [children release];
    
    [super dealloc];
}

- (void)finalize
{
    title = nil;
    identifier = nil;
    icon = nil;
    children = nil;
    
    [super finalize];
}

#pragma mark -
#pragma mark Custom Accessors

- (BOOL)hasBadge
{
    return badgeValue!=-1;
}

- (BOOL)hasChildren
{
    return [children count]>0;
}

- (BOOL)hasIcon
{
    return icon!=nil;
}

@end

// ======================
// = File AppDelegate.m =
// ======================

#import "AppDelegate.h"
#import "SourceListItem.h"

@implementation AppDelegate

#pragma mark -
#pragma mark Init/Dealloc

- (void)awakeFromNib
{
    [selectedItemLabel setStringValue:@"(none)"];
    
    sourceListItems = [[NSMutableArray alloc] init];
    
    //Set up the "Library" parent item and children
    SourceListItem *libraryItem = [SourceListItem itemWithTitle:@"LIBRARY" identifier:@"library"];
    SourceListItem *musicItem = [SourceListItem itemWithTitle:@"Music" identifier:@"music"];
    [musicItem setIcon:[NSImage imageNamed:@"music.png"]];
    SourceListItem *moviesItem = [SourceListItem itemWithTitle:@"Movies" identifier:@"movies"];
    [moviesItem setIcon:[NSImage imageNamed:@"movies.png"]];
    SourceListItem *podcastsItem = [SourceListItem itemWithTitle:@"Podcasts" identifier:@"podcasts"];
    [podcastsItem setIcon:[NSImage imageNamed:@"podcasts.png"]];
    [podcastsItem setBadgeValue:10];
    SourceListItem *audiobooksItem = [SourceListItem itemWithTitle:@"Audiobooks" identifier:@"audiobooks"];
    [audiobooksItem setIcon:[NSImage imageNamed:@"audiobooks.png"]];
    [libraryItem setChildren:[NSArray arrayWithObjects:musicItem, moviesItem, podcastsItem,
                              audiobooksItem, nil]];
    
    //Set up the "Playlists" parent item and children
    SourceListItem *playlistsItem = [SourceListItem itemWithTitle:@"PLAYLISTS" identifier:@"playlists"];
    SourceListItem *playlist1Item = [SourceListItem itemWithTitle:@"Playlist1" identifier:@"playlist1"];
    
    //Create a second-level group to demonstrate
    SourceListItem *playlist2Item = [SourceListItem itemWithTitle:@"Playlist2" identifier:@"playlist2"];
    SourceListItem *playlist3Item = [SourceListItem itemWithTitle:@"Playlist3" identifier:@"playlist3"];
    [playlist1Item setIcon:[NSImage imageNamed:@"playlist.png"]];
    [playlist2Item setIcon:[NSImage imageNamed:@"playlist.png"]];
    [playlist3Item setIcon:[NSImage imageNamed:@"playlist.png"]];
    
    SourceListItem *playlistGroup = [SourceListItem itemWithTitle:@"Playlist Group" identifier:@"playlistgroup"];
    SourceListItem *playlistGroupItem = [SourceListItem itemWithTitle:@"Child Playlist" identifier:@"childplaylist"];
    [playlistGroup setIcon:[NSImage imageNamed:@"playlistFolder.png"]];
    [playlistGroupItem setIcon:[NSImage imageNamed:@"playlist.png"]];
    [playlistGroup setChildren:[NSArray arrayWithObject:playlistGroupItem]];
    
    [playlistsItem setChildren:[NSArray arrayWithObjects:playlist1Item, playlistGroup,playlist2Item,
                                playlist3Item, nil]];
    
    [sourceListItems addObject:libraryItem];
    [sourceListItems addObject:playlistsItem];
    
    [sourceList reloadData];
}

By using “special” dictionaries, we can greatly reduce code size, and enhance flexibility

Clojure has the concept of “records”. These are basically “special dictionaries” (AKA maps). Clojure uses maps/dictionaries all over the place, because it realizes that it’s not only not necessary to create a new class for every type of data you have, but it’s counter-productive.

Today I spent some time adapting the idea of Clojure’s records into its Objective-C equivalent simply through the creation of categories on the NSDictionary and NSMutableDictionary classes. The result is that I was able to reproduce the screenshot above with the following code (equivalent sections to the ones above):

// ======================
// = File AppDelegate.m =
// ======================

#import "AppDelegate.h"

@protocol SourceListItem
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *identifier;
@property (nonatomic, retain) NSNumber *type;
@property (nonatomic, retain) NSImage *icon;
@property (nonatomic, retain) NSMutableArray *children;
@end

@implementation AppDelegate

- (void)awakeFromNib
{
    sourceListItems = [[NSMutableArray alloc] initWithObjects:
                       _MD(@"title", @"LIBRARY",
                           @"identifier", @"library",
                           @"children",
                           NSARY(_MD(@"title", @"Music",
                                     @"identifier", @"music",
                                     @"icon", NSIMG(@"music")),
                                _MD(@"title", @"Movies",
                                    @"identifier", @"movies",
                                    @"icon", NSIMG(@"movies")),
                                 _MD(@"title", @"Podcasts",
                                     @"identifier", @"podcasts",
                                     @"icon", NSIMG(@"podcasts")),
                                 _MD(@"title", @"Audiobooks",
                                     @"identifier", @"audiobooks",
                                     @"icon", NSIMG(@"audiobooks")))),
                       _MD(@"title", @"PLAYLISTS",
                           @"identifier", @"playlists",
                           @"children",
                           NSARY(_MD(@"title", @"Playlist1",
                                     @"identifier", @"playlist1",
                                     @"icon", NSIMG(@"playlist")),
                                 _MD(@"title", @"Playlist Group",
                                     @"identifier", @"playlistgroup",
                                     @"icon", NSIMG(@"playlistFolder"),
                                     @"children",
                                     NSARY(_MD(@"title", @"Child Playlist",
                                               @"identifier", @"childplaylist",
                                               @"icon", NSIMG(@"playlist")))),
                                 _MD(@"title", @"Playlist1",
                                     @"identifier", @"playlist1",
                                     @"icon", NSIMG(@"playlist")),
                                 _MD(@"title", @"Playlist1",
                                     @"identifier", @"playlist1",
                                     @"icon", NSIMG(@"playlist")))),
                       nil];
    [sourceList reloadData];
}

Not only is the code above more flexible and significantly shorter, but it’s clearer as well! You can practically visualize the GUI’s structure from the code itself!

The rest of the code (related to the delegate methods) is essentially equivalent, except it’s again, shorter.

“Magic” Dictionaries with Properties!

Dictionaries are created using the _MD and _D macros (for creating mutable and immutable dictionaries, respectively). These are plain old standard Foundation dictionaries. They can be saved to the hard disk, read back, key-value coded, etc. The reason for the macros is code brevity and because they use a new dictionaryWithKeysAndObjects: method that’s added to all dictionaries through the categories (I have no idea why Apple’s engineers throught it would be better to have values come before keys as with dictionaryWithObjectsAndKeys:…).

Next, let’s have a look at how dictionary values are manipulated and obtained. Most semi-intelligent languages have a map literals and simple syntax for fetching and setting map key/value pairs. Objective-C has no such intelligence imparted to it. However, it does have the very nifty forwardInvocation: mechanism. By combining forwardInvocation: with Objective-C protocols and properties, it’s possible to create “Objective-C records”.

Instead of this:

- (NSUInteger)sourceList:(PXSourceList*)sourceList numberOfChildrenOfItem:(id)item
{
    //Works the same way as the NSOutlineView data source: `nil` means a parent item
    if(item==nil) {
        return [sourceListItems count];
    }
    else {
        return [[item children] count];
    }
}

We can now use the dot-syntax notation to do this:

- (NSUInteger)sourceList:(PXSourceList*)sourceList numberOfChildrenOfItem:(id<SourceListItem>)item
{
    return item ? [item.children count] : [sourceListItems count];
}

Behind the scenes, item.children is turned into [item objectForKey:@"children"].

Setting values is also done through the standard dot-notation of Objective-C properties:

- (void)sourceList:(PXSourceList*)aSourceList setObjectValue:(id)object forItem:(id<SourceListItem>)item
{
    item.title = object;
}

Grab on Github

You’ll find the project for TERecord here, and the converted example of PXSourceList here.

Espionage 2.8.9 Released!

The changes below have been updated to include those of 2.8.10.

An important maintenance update on the road to 2.9!

  • NEW: Sparrow application template
  • IMPROVED: SmartMove is now even smarter (detects change in parent folder location at lock/unlock).
  • IMPROVED: Added documentation on how to recover from a corrupt database
  • IMPROVED: Espionage can create folders that haven’t been created yet (but should be, like “Mail Downloads”)
  • SECURITY: Remind user to secure-empty trash after changing the encryption on a folder
  • FIXED: 2.8.8 broke Backup on Lock
  • FIXED: “Don’t have a record for it” messages wouldn’t go away
  • FIXED (2.8.10): Apps did not get associated properly in 2.8.9

SmartMove Improved

Espionage’s SmartMove feature gets an update in this version, making it more robust. Previously, Espionage was only able to track when the folder itself was moved, but would lose track of it if one of the parent folders were moved or renamed. Now, Espionage will sync up with the folder’s new location once the folder is locked or unlocked. All of the code related to moving and renaming folders has also been consolidated into one main class.

Enjoy! :-D

DelayedLauncher 2.2

DelayedLauncher gets an icon thanks to Lorenzo Orlandi! :)

  • NEW: New icon by @lorenzorlandi — thanks!!
  • NEW: Reveal In Finder contextual menu item


Requirements: Mac OS X 10.4+

Espionage 2.8.8 Released + Microsoft Outlook Tutorial

  • NEW: Evernote application template (be sure to quit the Elephant in the menubar before encrypting!)
  • NEW: Instructions for Microsoft Outlook
  • IMPROVED: iCal template associates Mail with the Calendars folder now because of Todos
  • IMPROVED: Outdated backups of sparseimages (when folder changed to sparsebundle) are deleted (and vice versa)
  • FIXED: Rare situation where Espionage’s main window wouldn’t show because of recent updates
  • FIXED: Issue where templates wouldn’t work if some core apps were deleted (like iPhoto, etc.)
  • FIXED: Rare hang that could occur during simultaneous backup + changing encryption of folder
  • FIXED: Possibly fixed issue encrypting folders outside of a FileVault encrypted Home directory, testing needed

Using Espionage With Microsoft Outlook

Espionage + Microsoft Outlook

We’re happy to announce that with the release of Office 2011, Microsoft has fixed an issue that made encrypting Entourage data with Espionage difficult. Now, Entourage is replaced by a program called Outlook, and while there are technical reasons as to why we can’t include an application template for Outlook, you can encrypt Outlook’s data with Espionage. Below are the instructions:

Step 1 – Quit all open Office Programs and Microsoft Messenger

Before messing with an application’s data, make sure it’s not running!

Step 2 – Drag the “Microsoft User Data” folder onto Espionage

It’s located in:

/Users/[your username]/Documents/Microsoft User Data

Step 3 – Associate this folder with *all* Office applications

Microsoft’s applications can access each others data, and because of this it makes more sense to just encrypt the entire Microsoft User Data folder instead of attempting to isolate individual folders (you’re welcome to try encrypting more specific folders, just make sure to keep backups).

So, the next step is to locate the Microsoft Office folder and drag all the applications in it onto the box near the bottom. If you use Microsoft Messenger, associate that as well (that will also keep your chat logs secured):

Step 4 (Optional) – Keep the folder unlocked while logged in

Since so many applications are associated with this folder, you might want to just have the folder remain unlocked while you are logged into your user account. You can do this by checking the Autounlock At Login checkbox for the folder (in Espionage), and also disabling the Lock On Quit checkbox by editing the application associations on the folder. If you choose to do this, just make sure to enable your screensaver password (in Apple’s Security System Preferences).

That’s It!

Your Office data and emails are now encrypted.

Enjoy! :-D

Happy Holidays from Tao Effect!

Hey there blog readers!

Hope your holiday break is going *fantastically well*!

If it’s going less then stellar, remember, what matters most is not so much the situation that you find yourself in, but how you decide to react to it.

I was reminded of this during a walk today, where I saw plenty of examples of people who have very few possessions or the “luxuries of modern day life”. Though they probably didn’t get a Kindle or an iPad under their non-existent Christmas tree, they nevertheless were smiling, cracking jokes, and some were jamming on one instrument or another. I’m sure every passerby’s day was improved as a result. Their joy was contagious—it certainly made me smile.

This, I think, is what the Christmas spirit is really about. No matter where you find yourself, you get to choose how you react to your circumstances, and some of the best gifts you can give don’t cost a penny.

Happy Holidays,

Your Friends at Tao Effect

Espionage 2.8.6 Released!

The changes below have been updated to include those of 2.8.7.

Espionage 2.8.6 is finally out, and it’s highly recommended as it fixes many important issues and adds plenty of polish:

  • IMPROVED: Intelligence of application templates w.r.t. dependencies and more
  • IMPROVED: “Choose Password” changes to “Password Required” when re-adding an encrypted folder to Espionage
  • IMPROVED: Espionage now takes steps to resolve a situation when two disk images exist for one folder
  • IMPROVED: Added documentation on ‘saved’ folders and other advanced preferences
  • FIXED: “Lock Folder” contextual menu item not showing up
  • FIXED: Handling of ‘saved’ folders. See new preference in Advanced preferences
  • FIXED: Issue where device syncing could be disabled due to conflict with SyncServices
  • FIXED: Size check is not necessary for already encrypted folders
  • FIXED: Scroll bar wasn’t visible for the small association box when adding a folder to Espionage with too many associations
  • FIXED: Unnecessary associations suggested when adding Mail folder(s) directly to Espionage instead of via the template
  • FIXED: Hang that could occur if application association is launched independently during autounlock
  • FIXED: Rare issue where user could be prompted for login keychain password despite using separate keychain
  • FIXED (2.8.7): Previous version caused login keychain to lock if Espionage was set to use the login keychain
  • FIXED (2.8.7): Corrected explanation in documentation for calculating folder capacity

Overview of Significant Changes

Advanced preference for handling “saved folders”

Some users reported getting excessive “saved folder” notifications, and this release includes a new advanced preference for fine tuning how Espionage handles this situation. Details are in the new documentation on the advanced preferences.

“Lock Folder” contextual menu revived

It turns out that in switching to launchd, we inadvertently broke the “Lock Folder” contextual menu on 10.6. This situation has now been rectified, and the way we’re doing it now means that new users don’t have to restart their computers after installing Espionage for it to become visible.

Other important bug fixes

The release includes other important bugfixes, including a rare and bizarre issue where iSync would disable itself, and a hang that could be triggered during the autounlock sequence.

In short, it’s an important release, and you can update your copy within Espionage by launching it and choosing “Check For Updates…” from the Espionage menu.

Enjoy! :-D

Espionage 2.8.4 Released!

The changes below have been updated to include those of 2.8.5.

Espionage 2.8.4 is out! Here are the changes:

  • IMPROVED: SyncServices folder is now encrypted for many apps. Espionage tries to make sure it remains unlocked
  • IMPROVED: The ‘Lock On Quit’ option is now per-folder instead of per-application
  • IMPROVED: Relationship between ‘autounlock at login’ and ‘launch at login’
  • IMPROVED: Miscellaneous improvements
  • NEW (2.8.5): Added “Open Espionage” menu item to Espionage’s global menu
  • FIXED (2.8.5): Rare minute-long hang when an app was launched immediately after another was unlocked
  • IMPROVED (2.8.5): Added a warning regarding encrypting folders beginning with an underscore

‘Lock On Quit’ is now per-folder

Previously, when the ‘Lock On Quit’ checkbox was checked, it applied to all folders. In other words, if an application had two folders associated with it, it wasn’t possible to have only one of those folders lock when the application quit.

Now it is. :-)

The “special” SyncServices folder

There’s a folder in OS X called SyncServices, located here:

/Users/[your username]/Library/Application Support/SyncServices

Any application that wants to have its data synced by OS X (whether through iTunes or possibly iSync), might have some of that data stored here. As this folder can be used by various applications, including ones that aren’t explicitly associated with the folder, it’s recommended to keep this folder unlocked the entire time you’re logged into your user account.

Most of the data in this folder is fairly non-important (for example, Mail keeps your email in a different folder, but some things, like Notes and account settings, can be stored in the SyncServices folder), and difficult to decipher, so it’s fine to leave it unlocked while you’re logged in. If you’re concerned you can turn on the screensaver password in OS X’s Security System Preferences pane.

You can encrypt this folder by dragging it onto Espionage, or by re-running the application template for Mail, Safari, iCal, or Address Book if you already have any one of them encrypted. Espionage is already setup to treat this folder differently so you don’t have to worry about making sure it autounlocks when you login.

(Note: All Espionage’d folders are instantly re-locked the second the computer loses power, or you logout or restart.)

Enjoy! :-D

Espionage 2.8.3 Released!

Espionage 2.8.3 is a minor point update with some significant changes:

  • NEW: Converted EspionageHelper to launchd agent, resulting in improvements to:
    • Improved security for non-enrypted folders (which are still obviously insecure)
    • Removes startup errors associated with Apple’s buggy Login Items code
    • Crash recovery
  • NEW: iPhoto application template
  • IMPROVED: Notification regarding moving or renaming unlocked encrypted folders.
  • IMPROVED: Updated iCal template to reflect changes by Apple
  • FIXED: Check to prevent encryption of Library folder
  • FIXED: Rare situation where incorrect applications would be suggested as associations for a folder
  • FIXED: SmartMove did not update app associations
  • FIXED: Unnecessarily re-prompted for master password when stopping helper from preferences

Good-bye Login Items, Hello launchd

Up until this version, Espionage used OS X’s login items facility to start its helper program, which runs in the background and is responsible for bringing up the password prompt, unlocking folders, etc.

We chose this method because it was the only reliable way to have a program start at login on both Mac OS 10.5 (Leopard) and 10.4 (Tiger). It turned out, however, that Espionage was not compatible with 10.4 for various technical reasons, and we also noticed that in some rare cases, Apple’s code for putting something on the list of login items would break or flake out, so we’ve been eager to make the switch to what are called launchd agents, available in 10.5 and later, which act as super-powered login items.

Now, if Espionage’s helper crashes or is forcibly quit by the user incorrectly, it will immediately relaunch. This property enhances the “security” of unencrypted, password protected folders (which, don’t kid yourself, are still very much insecure, and are only useful for protecting relatively unimportant data from luddites).

There are other small benefits to switching to the agent system (and I won’t go into all of them), but needless to say, 2.8.3 is a rather significant update for a minor-point release, so updating to it is highly recommended!

Enjoy! :-D

Espionage 2.8 Introduces SmartMove!

We’ve been working hard to make Espionage even easier to use, and with 2.8 we think we made a little bit of a breakthrough in usability when it comes to moving and renaming folders. We call this new feature SmartMove.

That isn’t the only change in 2.8 though, here’s the complete list:

  • NEW: SmartMove – allows folders to be moved and renamed like normal, Espionage handles the details
  • NEW: Espionage now handles importing previously lost encrypted folders when given their symlink
  • NEW: Setting to prevent Time Machine from backing up a folder, available by right-clicking on a folder in the list.
  • NEW: Prompt user for folder password during restoration in the event of issues retrieving it from keychain
  • NEW: Remind user to enable Espionage’s backups if they’re not enabled.
  • IMPROVED: Backups made safer: Espionage won’t overwrite backups with folders that failed to unlock
  • IMPROVED: Better support for encrypting invisible folders (those that start with a dot)
  • IMPROVED: “Lock Folder” CM on 10.6 now properly locks folder if used on folder’s mountpoint
  • IMPROVED: Path Finder compatibility. Make sure to check Path Finder compatibility mode in the Preferences
  • IMPROVED: Ensure Finder is active after a folder is unlocked
  • FIXED: Issue with one of Espionage’s folder validation checks
  • FIXED: Issue where Finder could cause prompt to appear immediately after a folder is locked
  • IMPROVED (2.8.1): Minimized appearance of “Please lock” info alerts
  • IMPROVED (2.8.1): Folders on Time Machine’s blacklist are removed from it when restored
  • IMPROVED (2.8.1): Don’t allow non-encrypted folders to be added to Time Machine’s blacklist
  • IMPROVED (2.8.1): Documentation for restoring from Time Machine backups
  • FIXED (2.8.1): Problems importing invisible disk images
  • FIXED (2.8.2): Rare issue where Espionage could hang on first-unlock of a folder because of Spotlight

Overview of Significant Changes

SmartMove

Previously, moving or renaming folders wasn’t very intuitive, and while we were aware of this, we weren’t sure whether there was a robust enough technical solution to make the whole process more inuitive.

I’m happy to say though that we finally figured it out and now moving or renaming protected folders is as simple as… moving or renaming folders! :-)

I threw together a quick video showing off this feature:

Improved Time Machine Integration

Because Espionage moves a disk image each time a folder is locked or unlocked, Time Machine may end up backing up more than it needs to.

To ensure efficient backups with Time Machine, you can either make sure to run Time Machine when all folders are in the same locked state as they were during the previous backup, or, now with 2.8 you can prevent Time Machine from backing up a folder altogether (and use Espionage’s backups instead) for specific folders:

Stay tuned for more improvements in this area…

Updated Dropbox Instructions

We’ve also improved the instructions for using Espionage with Dropbox. The new-style setup lets Dropbox add its nice little badges on files and folders.

If you’re currently using the old-style setup and want to convert to the new way of encrypting Dropbox, it’s very simple:

  1. Open Dropbox and go into its preferences.
  2. Move the Dropbox to your home folder.
  3. When it’s done, move the Dropbox again, this time select the *unlocked* Vault folder (in your Home folder, it will have a little arrow icon on it) as the destination.

Enjoy! :-D