What is the database location of a MacOS application when using Core Data ?
I searched everywhere on my Mac and did't find it.
I Have the hidden files OFF and I'm sure there is data in my database.
Also I don't use app Sandbox.
If you have sandboxing enabled for your app, it will be placed under ~/Library/Containers/app.bundle.id/Data/Library/Application Support/AppTargetName where app.bundle.id is the Bundle Identifier specified in your app's target and AppTargetName is the name of that target, i.e. the name of the generated .app file. In that folder you should find the SQLite files that contain the database data.
Look for the persistentStoreCoordinator method in your AppDelegate.m. There is a line
NSURL *applicationDocumentsDirectory = [self applicationDocumentsDirectory];
Just add
NSLog(#"myDirectory: %#", applicationDocumentsDirectory);
This assumes you started your project with Xcode 8 Cocoa template with "use Core Data" option.
Or add
NSLog(#"Array of CD stores: %#", self.persistentStoreCoordinator.persistentStores);
to applicationDidFinishLaunching, for example. The resulting path should be in your user's library Users/<user>/Library/Application Support/<whatever>/<appname>.storedata.
Ask your NSPersistentStoreCoordinator.
Related
Question
Is it possible to determine the location a macOS app was launched from at runtime?
Context
I develop a Safari Extension, and in order for the extension to be enabled the application needs to be present /Applications/. Several users have tried to run the application directly from the DMG file and then complained that the extension doesn't appear in Safari's extension settings. I would like to detect this and alert them that they need to move the file.
You can use NSBundle, specifically the bundlePath property. The documentation says:
The full pathname of the receiver’s bundle directory.
And you can use it something like this:
NSString* bundlePath;
bundlePath = [[NSBundle mainBundle] bundlePath]
NSLog(#"%#", bundlePath);
There's also bundleURL if you want a NSURL to work with instead of a string.
I'm working on a little app that acts as a plugin for a 3rd party app. For it to function, I need to access a saved file from the 3rd party app ("other app" from here). In newer versions, the other app keeps this in ~/Application Support/Test App/Saved Files/.
This is easy to go to, using something like this:
NSString *savedFiles = [NSHomeDirectory() stringByAppendingPathComponent:#"~/Application Support/Test App/Saved Files"];
But I also want to make it compatible with older versions, and they don't use the application support folder. Older versions went in their folder in the user's applications folder, for example this structure:
~/Applications/Test App/Test App.app
~/Applications/Test App/Saved Files/
I can use the same as above to find the location to saved files. But the app won't always be installed here, or the folder name could be different in a different language. This is the problem.
I thought so far, I thought the following are options to get the path:
Ask the user to navigate to the file with a file selector from
within my app.
Ask the user where the "Test App.app" is, and get the
path via "../Saved Files/" relative to that.
Can the app get the path to a previously run application via the system?
Can the app use spotlight to quickly find the location?
Are there other ways to do this automatically, reliably, and quickly?
1 and 2 are not preferred, as that would require the user to "work" to give the app the path. What do you all think?
Are there other ways to automate this?
Which would be the fastest?
You can try to ask LaunchServices for the app's location, given its bundle identifier with the LSFindApplicationForInfo call:
CFURLRef urlRef = NULL;
LSFindApplicationForInfo(kLSUnknownCreator, (CFStringRef)#"com.example.some-app", NULL, NULL, &urlRef);
NSLog(#"URL: %#", (__bridge id)urlRef);
This assumes that the bundle identifier is the same between the two variants you mention. If it's really just the name that is the same, you could query by name instead:
CFURLRef urlRef = NULL;
LSFindApplicationForInfo(kLSUnknownCreator, NULL, (CFStringRef)#"Test App.app", NULL, &urlRef);
NSLog(#"URL: %#", (__bridge id)urlRef);
I'm trying to make an SDL application in Xcode, but I'm having trouble loading images. I'm using this template, because I couldn't get it to work when made from scratch.
Whenever I try to load an image with SDL_LoadBMP however, it returns NULL unless I give the absolute path. (/Users/Cole/code...) I looked in the exported .app file, and it does have the image I want to load in Contents/Resources/, and I've tried every combination I can think of to get at those (../Resources/image.bmp, ect.) but I can't seem to get it working.
Does anyone have a solution? I'm running Mac OS 10.7 with Xcode 4, so I can't use the templates that is within the SDL download.
Also, I tried using SDL_ttf, but I get this error:
warning: Unable to read symbols for #executable_path/../Frameworks/SDL_ttf.framework/Versions/A/SDL_ttf (file not found).
warning: Unable to read symbols from "SDL_ttf" (not yet mapped into memory).
There does not happen to be a Frameworks folder where it's looking, but somehow it finds the regular SDL framework just fine.
You can get the path to your the Resources directory containing your file with
NSString *path = [[NSBundle mainBundle] resourcePath];
or alternatively (in theory more clean as it can access localized files) you can get the full file name with
NSString *file = [[NSBundle mainBundle] pathForResource:#"image.bmp" ofType:nil];
You'll need to pass the C string to SDL_LoadBMP, so either of the two:
SDL_LoadBMP([[path stringByAppendingString: #"/image.bmp"] UTF8String]);
SDL_LoadBMP([file UTF8String]);
I had the same problem and found a way without using any objective-c.
In xcode click on your target then go onto the build phase section
Then in the top bar click: Editor -> Add Build Phase -> Add Copy Files Build Phase
Now change the destination of the newly created phase to "Products Directory" and then add any subpaths if needed.
All you need to do now is add your image onto the list below and it should work!
Are there any restrictions as far as saving files when you distribute an app over the Mac App Store?
If I compile and run my app from my computer it works fine - it saves the configuration.
However the version that was downloaded over the Mac App Store is not saving the configuration. I don't even see the config file. Anyone knows what is going on?
This is the code that saves the config:
-(void)saveConfig:(id)plist {
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString: CONFIG_FILE_NAME];
NSData *xmlData;
NSString *error;
xmlData = [NSPropertyListSerialization dataFromPropertyList: plist
format: NSPropertyListXMLFormat_v1_0
errorDescription: &error];
if(xmlData)
{
if (![xmlData writeToFile:path atomically:YES])
NSLog(#"Failed to write the config file onto the hard drive");
}
else
{
NSLog(error);
}
}
You cannot write files to the application bundle directory if you’re targeting the Mac App Store. The bundle is supposed to be immutable.
Consider saving your configuration with NSUserDefaults or, if you truly need a separate file, the officially recommended location is (~)/Library/Application Support. Matt Gallagher wrote a nice post called Finding or creating the application support directory in which he provides a solution that uses standard NSApplicationSupportDirectory followed by the executable name.
Generally, you should assume that your application's assets are read-only. This is true in general, not just for the app store.
If you want to save user settings as a property list, use NSUserDefaults instead of modifying files inside the application. This will "just do the right thing", which is to save preferences to ~/Library/Preferences.
I'm playing around with CoreData in a Mac OS X application. After changing an entity i got the following error:
The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store.
All answers i've found for this issue suggest implementing versioning/migration into the app, but I'm not interested in saving my data. Isn't there a less complicated solution for that? Like deleting the stock file or something like that? And if yes, where is this file located?
Thanks.
If you don't want the data, then yes, you can simply delete the old file and create a new one. If your data is document based, then the document itself should be deleted. If you use a single store for the whole application (not document based), then you should look in the code that creates the store object to find the location. The template places the creation code in the application delegate, and the default location for the store is in ${HOME}/Library/Application Support/${APP_NAME}/.
On OS X 10.7 Lion when the app is sandboxed, it is stored in:
~/Library/Containers/com.yourcompany.yourAppName/
I found that for Mac OS X 10.8 / Xcode 4.6 the data is stored in the derived data folder of under
Users/*username*/Library/Developer/Xcode/DerivedData/*app name*-*random string*/Build/Products/Debug/*app name*.sqlite
The easiest way to delete this data is to go to the organiser, select project tab and click "Delete..." button by derived data.
Alternatively, For OSX, use the Nsfilemanager to delete the file by using the url defined in the lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator{...}
In this var persistentStoreCoordinator a url will be defined that is designed to be used by the persistentStoreCoordinator. You can just use the url defined there to delete the old store. Insert the below code. Run the project and the file will be deleted. Then delete the code to allow objects to be stored again and not delete the data every time.
here is what I found in the lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CocoaAppCD.storedata")
here is what i put immediately underneath it.
do{
try NSFileManager.defaultManager().removeItemAtURL(url)
} catch{
print("could not delete file")
}
then i clicked run. It ran once then i delete the code i just made so that the data would not be deleted every time
In macOS Big Sur (11.4), local NSPersistentCloudKitContainer Core Data storage can be found at:
~/Library/Containers/yourAppName/Data/CloudKit/
On Mac OS X 10.11.4 with Xcode 7.3 cleaning the fixed the problem for me:
Product > Clean or Shift⌘K
Try to run the app in a simulator of another device that you haven't used before and see if it helps you (i.e. iPhone SE instead of iPhone 7). If it does, then removing the corrupted folders should help. Open Terminal and run the following commands:
sudo rm -rf ~/Library/Developer/CoreSimulator/Devices
to remove the simulators' data that might be corrupted,
sudo rm -rf ~/Library/Developer/XCode/DerivedData/
to remove your app's data.
Hope that helps!