selbie
selbie

Reputation: 104559

Run code on either uninstall or re-install of Mac app

For a Mac app, written in Cocoa/Objective-C, a common customer support problem is that they tried "uninstalling and re-installing" in hopes of getting back to a clean state. But the problem is that the new install is still reading the configuration files and database left by the previous install. Customer just hits the same issue that caused him to uninstall in the first place. Then I have to guide him through which files to delete to get back to an OK state and/or show him the proper way to reset from the UI.

While the real pain points and bugs get fixed over time, I'd like to know if it is possible to do either of the following:

  1. When MyApp.app is moved to the trash bin, is it possible for some code can run that cleans up any crud left by the app in the user's home directory? Or something in a manifest/pinfo file that can designate certain directories or files be removed?

OR

  1. When the application is started, that it can programatically detect that it has been "re-installed" such that it can do the necessary cleanup code for the new install?

Upvotes: 0

Views: 351

Answers (2)

Mecki
Mecki

Reputation: 133019

NSString * appPath = [[NSBundle mainBundle] bundlePath];
NSDictionary * fileAttribs = [[NSFileManager defaultManager]  
    attributesOfItemAtPath:appPath error:nil
];
NSDate * creationDate = [fileAttribs objectForKey:NSFileModificationDate];

NSDate * savedDate = [[NSUserDefaults standardUserDefaults] 
    objectForKey:@"AppBundleFileModificationDate"
];

if (!savedDate) {
    // ... App never ran before ...
} else if (![creationDate isEqual:savedDate]) {
    // ... App did run before, 
    // but bundle has been re-installed or updated ...
} else {
    // ... App did run before and has not 
    // been re-installed or updated ...
}

[[NSUserDefaults standardUserDefaults]
    setObject:creationDate forKey:@"AppBundleFileModificationDate"
];

How can you distinguish a re-install from an update? Save the app version as well, if it was an update, it has changed, it not, it's a re-install of the same version.

The code will incorrectly detect a re-install if the user moves the app to a different directory and starts it from there. You can catch that case if you also store the appPath and compare that as well.

What you write to NSUserDefaults survives as long as the user doesn't deletes the preferences of the app, which never happens automatically on Mac.

Upvotes: 0

CRD
CRD

Reputation: 53000

On app startup you could consider:

  1. The app version number
  2. The path to the app
  3. The inode of the app, i.e. the inode of the .app directory

Store old values of these in the app's prefs/application support, compare against current on launch. Based on heuristics you can decide/guess if an app has been updated (1st), moved/copied/multiple copies (2nd), deleted and re-created (3rd), or something else. It's not perfect, it is possible a re-created app has the same inode number, but its unlikely and certainly if it does change you know its a different directory.

HTH

Upvotes: 2

Related Questions