Where is the correct place to store a Mac application's database? - macos

I'm building an application that I hope to submit to the Mac App Store. The app has an SQL database that stores all of the items that the user has created.
Does anyone know where I should be storing this to comply with Apple's guidelines? Should it go in Application Support, the Documents folder, the Library or somewhere else??

Generally, you shouldn't automatically create file in the user home directory, except in ~/Library/Application Support/<Application>. So either let the user choose where to store the information (if it is document centric), or store it in Application Support.
See the question: What location do OSX/Cocoa applications generally use to store data files?

Related

Save Data Within Signed App

I am distributing my OS X application on individual USBs and, for this reason, everything must be self contained.
The app itself lets users input information and then saves this information to an existing text file (specifically an ObjectDB database). Herein is my problem.
I'd like to keep this text file inside the app itself (i.e. inside the Content folder) so it's out of the way and can't be deleted by the average user. But once the app is signed, it seems the text file can't be altered with any new information without getting flagged by Gatekeeper. Is this really the case? There's no way to store data files within apps now?
I'd appreciate any suggestions. Thanks.
Yes, you are correct. If you modify the application package, the signed package is no longer valid. That's kind of the purpose of signing a package.
Your options are to store the text file in a temporary folder on the user's computer, or to instruct your users to disable gatekeeper (don't do this).

Display PDF file in LocalState folder in Windows 8 app in Cordova

My application downloads a PDF and stores it in the LocalState folder for my Windows 8 app.
I have a link within the app that I would like to show the PDF when the user clicks it.
I've tried displaying it using ms-appdata:///local/pdfs/filename.pdf in a window.open call and I also tried using the InAppBrowser plugin within cordova with no luck. Additionally, I've tried the following:
var uri = new Windows.Foundation.Uri('ms-appdata:///local/pdfs/filename.pdf');
var file = Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri);
Windows.System.Launcher.launchFileAsync(file).done();
I know the file exists as I'm getting a file result back. Just not sure how to allow the user to view it.
By design, the local appdata folder on Windows is accessible only to that app, or to full-trust desktop applications (and this is probably true of similar sandboxed locations on other platforms). As a result, a Windows Store app that gets launched with Launcher.launchFileAsync won't be able access that location (nor can a webview process, which is also sandboxed). If a desktop application gets launched, on the other hand, it probably can access the file, but you can't tell ahead of time if that's the case. Bottom line is that local appdata isn't a good location for letting other apps get at the file.
You'll need to save the file in another location that is accessible to other apps. There are two approaches here, both of which will require a little user interaction to select a location, so they can place the PDFs anywhere they want:
Have the user select a save folder for your app, which they can do once. You would invoke the FolderPicker for this purpose, and save the selected folder in the FutureAccessList. This way you can have the user select the save folder, which grants you consent to save there, and by saving it in the FutureAccessList you can retrieve it in subsequent sessions without having to ask the user again. Refer to the File Picker Sample and the File Access Sample for more.
Have the user select a save location for each individual file, using the FilePicker (see the same sample), and you can also use the access cache to save permissions to those individual locations if you need them later.
There might be Cordova plugins that work with these APIs too, but I haven't checked. Either way, once the file is in an accessible location, launching the file should work just fine.
As an alternate solution, you could consider rendering the PDFs directly in your app. Windows has an API for this in Windows.Data.Pdf, with an associated sample. There might be a plugin or other JS libraries that could also work for this.

Resetting mac application in xcode

How can I reset a cocoa application in Xcode? When I run my application from Xcode all user default are saved. I would like to reset (delete) my application to create a new one with new settings and run as it would be run first time.
I found one way - I change a name of my app to a different one and it is started as new. But how can I do this with an old name?
You can use the defaults command line tool to remove all the settings, you just need the bundle id of your app (which you can find in your Info.plist file), e.g. if your bundle id is "com.foo.barApp" then you can run this from a terminal shell:
defaults delete com.foo.barApp
Is your app limited to the App Store? If so, I don't think there's a way to delete your entire application, specifically because of the sandbox restrictions. We'd need more information on how you are planning to distribute it to help.
If you just want to delete your app settings, then clear whatever database you store your app data in - [NSUserDefaults +resetStandardUserDefaults], SQLite, App Library directory, whatever. That is dependent on how/where you are storing user data, there's no one size fits all solution.

overriding Mac app file associations via CFBundleDocumentTypes in info.plist

I develop a Mac app that saves and loads files of a unique type. The type is properly declared in the info.plist under CFBundleDocumentTypes, listed as LSHandlerRank: Owner and CFBundleTypeRole: Editor. I am releasing a new version of my app and I would like that if users who already have a previous version of my app on their machine install the new version but keep the old version also installed, the new version automatically takes over the file association for this type from the old version of the app. But the default OS behavior seems to be to grant the earliest installed app associated with a file type to be it's permanent owner unless the user manually changes it. I know that the command line tool duti can make association changes, and also the system file com.apple.LaunchServices.plist can be edited, but these don't seem like the best or most reliable way to go about this programmatically from an app. Is there any "right"/Apple-sanctioned way to do what I want?
The official, Apple-sanctioned way for an application to set the default application for a file type is probably to use their provided LSSetDefaultRoleHandlerForContentType function. This function sets the values stored in LaunchServices.
Here is the limited official documentation on how to use this API in Objective-C and Swift.
There doesn't appear to be any way to do this via Info.plist, as the first application get's set as the user preferred application. The user must change their preferred application, which you can facilitate with the above API.

Cocoa: how to Write file inside package contents of app

When we try to delete/uninstall Cocoa .app file ,we directly move the .app file to trash.
This does not ensure the deletion of app user data folder in application support.
The user data lies there hanging. So i wanted to save the user data/ files inside application itself (app->showPacakge contents->somewhere).
If it is not possible! Any ways of clearing app user data folder in application support when user moves app to trash ?
Not a great idea.
The package content is signed. Any modification will be detected by the OS and will prevent launching of the app.
Not to mention the fact that you might not have access to the Applications folder, where most users will keep their app.
if you are using packages for installing your application, then you can have pre-install script, which deletes user data in the application support folder.

Resources