Writing to Application Support in PyObjC
When writing a Cocoa app with PyObjC it can be easy to fall into the bad habit of storing the wrong kind of data inside the .app
folder. For example, in an application I am writing I use an SQLite database which I access from inside the .app
folder like this:
import os,sqlite3
def getDatabase(self):
path = os.path.join(os.path.dirname(__file__),'my_dict.sqlite')
return sqlite3.connect(path)
Because that database contains immutable data, storing it inside the .app
folder is an appropriate place for it to exist. However, in that same app I also need to store some user specific data. Unlike the immutable database, the correct place to store user specific data is in a subfolder of ~/Library/Application Support/
.
The function to calculate that folder can be implemented like this:
import os
from AppKit import *
from Foundation import *
def applicationSupportFolder(appname=u"MyAppNameHere"):
paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,True)
basePath = (len(paths) > 0 and paths[0]) or NSTemporaryDirectory()
fullPath = basePath.stringByAppendingPathComponent_(appname)
if not os.path.exists(fullPath):
os.mkdir(fullPath)
return fullPath
That will allow us to find the support folder for any application (as long as we know its name), but we can make it even more useful by building a second function on top which builds the complete path for a given filename.
def pathForFilename(filename,appname=None):
base = (appname and applicationSupportFolder(appname)) or applicationSupportFolder()
return base.stringByAppendingPathComponent_(filename)
Using pathForFilename
looks like this:
path = pathForFilename('user_data.xml','my_app')
fin = open(path,'r')
prefs = SomeCustomPythonClass(fin.read())
Let me know if there are any questions or comments.