The right and wrong way to save file paths in Titanium

By | August 31, 2015

If your app requires you to save files, perhaps photos that the user snapped using your app, your first thought might be to do something like:

// don't do this:
var file = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
file.write(imageBlobData);
// saving the full nativePath to the DB
myModel.set('filepath', file.nativePath);
myModel.save();
console.log(file.nativePath);

Unfortunately, you cannot count on the nativePath remaining constant between app versions. Run this sort of app on iOS, check the console output, and you’d find:

// with the first run of the app:
/var/mobile/Containers/Data/Application/551B24CF-1186-4DDC-B31D-19C03DA2A19D/Documents/myfile.jpg
// after updating the app:
/var/mobile/Containers/Data/Application/47A737A9-D284-43FA-AF1C-FD24872C88EE/Documents/myotherfile.jpg

The app’s GUID has changed and your stored file path is no longer valid. While the structure of Android file paths are different, the same general problem exists on Android as well. This means that if you had some place in your app where you did the following, you’d have broken images due to invalid file paths after an update.

myImageView.image = myModel.get('filepath');

The old files are probably still there. Just your explicit reference to their location is now invalid. Instead, you should do:

// right way:
var file = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
file.write(imageBlobData);
// save only the file's name
myModel.set('filepath', filename);
myModel.save();
// then this will work even after an upgrade
myImageView.image = Ti.Filesystem.applicationDataDirectory + myModel.get('filepath');