Xcode 6 iPhone Simulator Application Support location - ios

In Xcode 6, I have an app I'm using Core Data in, but there is no folder in Application Support for the iOS 8 iPhone Simulator. Where are my files and Core Data sqlite database being stored?

The simulator directory has been moved with Xcode 6 beta to...
~/Library/Developer/CoreSimulator
Browsing the directory to your app's Documents folder is a bit more arduous, e.g.,
~/Library/Developer/CoreSimulator/Devices/4D2D127A-7103-41B2-872B-2DB891B978A2/data/Containers/Data/Application/0323215C-2B91-47F7-BE81-EB24B4DA7339/Documents/MyApp.sqlite

I would suggest that you use SimPholders to find your Simulator files. It is a menu bar item that tracks your simulator apps and lets you go directly to their folders and content. It's awesome.

I found SimulatorManager application very useful. It takes you directly to the application folder of installed simulators. I have tried with 7.1, 8.0 and 8.1 simulators.
SimulatorManager resides as an icon in the system tray and provides an option to "Launch At Login".
Note: This works only with Xcode 6 (6.1.1 in my case) and above.
Hope that helps!

To know where your .sqlite file is stored in your AppDelegate.m add the following code
- (NSURL *)applicationDocumentsDirectory
{
NSLog(#"%#",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
now call this method in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//call here
[self applicationDocumentsDirectory];
}

This worked for me in swift:
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
println("App Path: \(dirPaths)")

I wrestled with this for some time. It became a huge pain to simply get to my local sqlite db. I wrote this script and made it a code snippet inside XCode. I place it inside my appDidFinishLaunching inside my appDelegate.
//xcode 6 moves the documents dir every time. haven't found out why yet.
#if DEBUG
NSLog(#"caching documents dir for xcode 6. %#", [NSBundle mainBundle]);
NSString *toFile = #"XCodePaths/lastBuild.txt"; NSError *err = nil;
[DOCS_DIR writeToFile:toFile atomically:YES encoding:NSUTF8StringEncoding error:&err];
if(err)
NSLog(#"%#", [err localizedDescription]);
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleName"];
NSString *aliasPath = [NSString stringWithFormat:#"XCodePaths/%#", appName];
remove([aliasPath UTF8String]);
[[NSFileManager defaultManager] createSymbolicLinkAtPath:aliasPath withDestinationPath:DOCS_DIR error:nil];
#endif
This creates a simlink at the root of your drive. (You might have to create this folder yourself the first time, and chmod it, or you can change the location to some other place) Then I installed the xcodeway plugin https://github.com/onmyway133/XcodeWay
I modified it a bit so that it will allow me to simply press cmd+d and it will open a finder winder to my current application's persistent Documents directory. This way, not matter how many times XCode changes your path, it only changes on run, and it updates your simlink immediately on each run.
I hope this is useful for others!

Open finder>Library>Developer>CoreSimulator>Devices
Then Change Arrangement icon from finder select Date Added
Select your app >data>Container>data>Applications>
choose your app >Documents>Here is your db file
In my case:
/Users/pluto/Library/Developer/CoreSimulator/Devices/A75107D2-A535-415A-865D-978B2555370B/data/Containers/Data/Application/265A12BC-FF5B-4235-B5EF-6022B83754B4/Documents/dboPhotoBucket.sqlite
Otherwise do this :
NSLog(#"app dir: %#",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
- It will print the full path to data folder.
Swift:
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
println("App Path: \(dirPaths)")

Use Finder-->go to folder and enter given basepath to reach application folders
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSLog(#"%#",basePath);

The simulator puts the file in ~/Library/Developer/CoreSimulator/Devices/... but the path after /Devices is different for everyone.
Use this handy method. It returns the path of the temporary directory for the current user and takes no argument.
NSString * NSTemporaryDirectory ( void );
So in my ViewController class I usually put this line in my viewDidLoad just for a reference when I need to grab my CoreData stored file. Hope this helps.
NSLog(#"FILE PATH :%#", NSTemporaryDirectory());
(Note: to go to the path, from the finder menu click on Go and type ~/Library to open hidden directory then in the Finder Window you can click on the path shown on your console.)

This location has, once again, changed, if using Swift, use this to find out where the folder is (this is copied from the AppDelegate.swift file that Apple creates for you so if it doesn't work on your machine, search in that file for the right syntax, this works on mine using Xcode 6.1 and iOS 8 simulator):
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
println("Possible sqlite file: \(urls)")

The simulators are located under:
~/Library/Developer/CoreSimulator/
Here, they are listed as directories with UUID names. Use sort by 'Date modified' to find the latest one. Inside navigate to:
/data/Containers/Data/Application/
Here you will get a list of all the applications on that device. You can again sort this to get the latest app.
NOTE: Xcode changes the directory name every time you run the app, so don't rely on making alias/short cuts on desktop.
The easiest way is to use the app here, which does everything automatically.

I created this script that will zip the latest app built for any simulator and zip it to the desktop.
https://gist.github.com/Gerst20051/8ca49d5afbf09007b3696fab6e9f425c
#!/bin/bash
DESTINATION_DIR="$HOME/Desktop"
APP_PATH=$(find ~/Library/Developer/CoreSimulator/Devices/*/data/Containers/Bundle/Application/*/*.app -type d -maxdepth 0 -print0 | xargs -0 ls -td | head -n1)
APP_DIRNAME=$(dirname "$APP_PATH")
APP_BASENAME=$(basename "$APP_PATH")
FILE_NAME="${APP_BASENAME%.*}"
cd "$APP_DIRNAME"
zip -qr "$DESTINATION_DIR/$FILE_NAME.zip" "$APP_BASENAME"

In Swift 4 or Swift 5 you can use NSHomeDirectory().
The easiest way in Xcode 10 (or Xcode 11) is to pause your app (like when it hits a breakpoint) and run this line in the debugger console:
po NSHomeDirectory()
po stands for print object and prints most things

1. NSTemporaryDirectory() gives this:
/Users/spokaneDude/Library/Developer/CoreSimulator/Devices/1EE69744-255A-45CD-88F1-63FEAD117B32/data/Containers/Data/Application/199B1ACA-A80B-44BD-8E5E-DDF3DCF0D8D9/tmp
2. remove "/tmp" replacing it with "/Library/Application Support/<app name>/" --> is where the .sqlite files reside

With Swift 4, you can use the code below to get your app's home directory. Your app's document directory is in there.
print(NSHomeDirectory())
I think you already know that your app's home directory is changeable, so if you don't want to add additional code to your codebase, SimPholder is a nice tool for you.
And further more, you may wonder is there a tool, that can help you save time from closing and reopening same SQLite database every time after your app's home directory be changed. And the answer is yes, a tool I know is SQLiteFlow. From it's document, it says that:
Handle database file name or directory changes. This makes SQLiteFlow can work friendly with your SQLite database in iOS simulator.

Here is the sh for last used simulator and application. Just run sh and copy printed text and paste and run command for show in finder.
#!/bin/zsh
lastUsedSimulatorAndApplication=`ls -td -- ~/Library/Developer/CoreSimulator/Devices/*/data/Containers/Data/Application/*/ | head -n1`
echo $lastUsedSimulatorAndApplication

Related

Where is my database file in xcode project

After I build an app with sqlite. I have installed SQLite manager in Firefox. Doesn´t help because I really don´t know where is that file. I tried many ways.
And finally I try to find this file
_databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"myUsers.db"]];
To open with MesaSQLite
Still have the same problem. Where is my file.
Here is the last way I have used:
/Users/{YOUR NAME}/Library/Developer/CoreSimulator/Devices/{DEVICE ID}/data/Containers/Data/Application/{APPLICATION ID}/
I still can not find it. I have open almost every project folders.
Please help me.
Dont open Library on MacintoshHDD. You need to open Library on your USERName Folder. There,normally library folder is hidden. You need to follow the following to see the hidden files.
Or simply copy paste the path into the search finder on your mac.It will take you directly.
The long way to show hidden Mac OS X files is as follows:
Open Terminal found in Finder > Applications > Utilities.
In Terminal, paste the following:
defaults write com.apple.finder AppleShowAllFiles YES.
Press return.
Hold 'alt' on your keyboard, then right click on the Finder icon in the dock and click Relaunch.
You should be able to find this using this method :
- (NSURL *)applicationDocumentsDirectory
{
NSLog(#"%#",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
Just copy paste whatever is logged in navigate into the folder where you stored your sqlite file
The end result should look like this :
~/Library/Developer/CoreSimulator/Devices/4D2D127A-7103-41B2-872B-2DB891B978A2/data/Containers/Data/Application/0323215C-2B91-47F7-BE81-EB24B4DA7339/Documents/MyApp.sqlite
Please note that the long ID's will obviously be different, as well as the file name.
You just following line of code to Log.
NSString *databasePath = [[NSBundle mainBundle] pathForResource:#"myUsers" ofType:#"db"];
Or use below code.
NSBundle* bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"myUsers" ofType:#"bundle"]];
NSLog(#"%#", bundle);
NSString* test = [bundle pathForResource:#"myUsers" ofType:#"db"];
NSLog(#"%#", test);
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:[bundle pathForResource:#"Root" ofType:#"plist"]];
NSLog(#"%#", dict);
I am using the Core Data Editor a lot for my iOS projects. It is compatible with Mac and iOS applications and support XML, SQLite and binary stores, etc. It is free. :-)
http://thermal-core.com/CoreDataEditor/

ios 8: Bundle path changes

I have an iOS app that stores the absolute path of files in a database and in generated html documents. I just recently updated my iPhone to iOS 8 and now when ever I run the app it seems that the app is installed in a different directory every re-compile. For example on the first build/run [[NSBundle mainBundle] bundlePath] returns something different on the next build/run. What is going on? Is this a new feature of Apple?
Update: A bug report was created
Code example:
If I run the following line over multiple build/runs then I will get a different result each time.
#define kOLD_PATH #"oldPath"
NSString* newPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString* oldPath = [[NSUserDefaults standardUserDefaults] objectForKey:kOLD_PATH];
NSLog(#"New Path: %#", newPath);
NSLog(#"Old Path: %#", oldPath);
NSLog(#"Result: %#", [oldPath isEqualToString:newPath] ? #"Same" : #"Changed");
[[NSUserDefaults standardUserDefaults] setObject:newPath forKey:kOLD_PATH];
[[NSUserDefaults standardUserDefaults] synchronize];
The output looks like this over multiple runs
New Path: /var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library
Old Path: /var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library
Result: Changed
Full Disclosure: In my app the user imports a web page (ePub) that has resources. The resources are stored with the web page. The web page also accesses resources that are part of the app bundle. To achieve this when I load the web page the base url is set to the directory the web page is in and the bundle resources are accessed via absolute file paths. Now that file paths change on every update this is broken. I tried creating symbolic links to the bundle resources but that also fails un subsequent updates.
In iOS 8, The file system layout of app containers has changed. Applications and their content are no longer stored in one root directory.
From the iOS 8 Release Notes:
The file system layout of app containers has changed on disk. Rather
than relying on hard-coded directory structure, use the
NSSearchPathForDirectoriesInDomains function or the
URLForDirectory:inDomain:appropriateForURL:create:error: method of the
NSFileManager class. See Accessing Files and Directories in File
System Programming Guide.
This is not a bug. Make sure you use the recommended APIs (from the above quote) and you won't have a problem.
So, If you are trying to access a bundled resource you added to the project, you would use:
[[NSBundle mainBundle] pathForResource:#"resourceName" ofType:#"extension"];
But if you want to use something that you put in the documents directory, you would use:
[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:#"resourceName.extension"];
Refer Technical Note 2406 by Apple
The breaking change is
Beginning in iOS 8, the Documents and Library directories are no
longer siblings of your application's bundle.
Don't store full path/URL to your documents. Store the file name and always generate full path/URL with recommended approach.
Get the DocumentsDirectory URL
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory {
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
Then you get path out of url and append the file name to generate full path.
don't know if you solved your problem, but this link is possible the answer.
https://developer.apple.com/library/prerelease/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html#//apple_ref/doc/uid/TP40010672-CH3-SW10
Locating Files Using Bookmarks
A few lines before this section in the page is this text:
"Important: Although they are safe to use while your app is running, file reference URLs are not safe to store and reuse between launches of your app because a file’s ID may change if the system is rebooted. If you want to store the location of a file persistently between launches of your app, create a bookmark as described in Locating Files Using Bookmarks."
Good bye.
I think the different path for each build and run is the intended way of things happening in iOS simulator. It is not an issue.
/var/mobile/Containers/Data/Application/4FFCE2CB-580D-409A-90CB-EF2B8A1FB653/Library
/var/mobile/Containers/Data/Application/B038B2DA-F85D-4E18-A5F1-8635834EC454/Library
I found even if you use the recommended way
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
}
The results are same. Different path for each build & run.

Change Path Directory to a specific location

I have this code who create a new database file:
// Get the documents directory
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"registros.db"]];
NSLog(#"DB Path: %#", databasePath);
This code always create in this directory:
DB Path: /Users/williamlima/Library/Application Support/iPhone
Simulator/7.0.3/Applications/0E94A6EA-B72F-4A11-88A9-EC8C1A55BF17/Documents/registros.db
Unfortunately I could not find this file and try to open the file manager. SQL, I would like to at least try to find this file, up or maybe try to modify some command in my code for this file to be created within the folder next to the files. h / .m / .xib, I'm still a beginner in this language, then, is this possible?
The files .h /.m / .xib are in your project and they get compiled (.m and .xib) and packaged into app. This app is installed on simulator. So first of all you won't see these files in simulator at following location
/Users/williamlima/Library/Application Support/iPhone Simulator/7.0.3/Applications/0E94A6EA-B72F-4A11-88A9-EC8C1A55BF17/
When you run the app, it will create file in Documents directory in your simulator app not in your project. That location is accessible by your code running in the app.
You can create directories which are explained in these questions:
How to make a directory iOS?
Is an iPhone app's document directory /var/mobile/Documents or /var/mobile/Library/AppName?
And then create files in those directories. I think you are confused why you don't see them in your project. The reason is it is created in the app location not in your project.

How can I check what is stored in my Core Data Database?

I am making an app that relies on Core Data. I am able to enter data into a text field and store it.
But I need to know if the data is being stored.
I am trying to make a detailView to my tableView and I am not getting any results. Now I am wondering is that because I am doing something wrong with my code, or is the data nto being stored properly.
How can I see what is stored in the app's CoreData database?
Here is my solution(works on iOS 9):
I use an automator/bash script that open the database in sqllitebrowser. the script finds the latest installed app in the simulator.
Instructions:
Install DB Browser for SQLite (http://sqlitebrowser.org/)
Create new workflow in Apple Automator.
Drag "Run Shell script block" and paste this code:
cd ~/Library/Developer/CoreSimulator/Devices/
cd `ls -t | head -n 1`/data/Containers/Data/Application
cd `ls -t | head -n 1`/Documents
open -a DB\ Browser\ for\ SQLite ./YOUR_DATABASE_NAME.sqlite
(Optional) Convert this workflow to application, save it and drag it to your dock. To refresh the database just click on the app icon.
Swift 4, 5
Add this line in AppDelegate >> didFinishLaunchingWithOptions function:
print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")
Your modelName.sqlite file will be there.
You can open it with any SQLite browser tools like http://sqlitebrowser.org/ that is free.
If you use sqlite as the storage media for Core Data, you can run your app in simulator and try to check the database file which is located in the sandbox's Library folder.
The path shall be something like: ~/Library/Application Support/iPhone Simulator/5.1/Applications/3BF8A4B3-4959-4D8F-AC12-DB8EF4C3B6E1/Library/YourAppName.sqlite
To open the sqlite file, you need a tool. I use a free tool called Liya (http://itunes.apple.com/us/app/liya/id455484422?mt=12).
The other solutions are either old or does not direct you easily or quickly to the SQLite files, so I came up with my own solution using FileManager.SearchPathDirectory.applicationSupportDirectory that gets the exact path where the sqlite file will be.
Solution #1 using FileManager.default:
func whereIsMySQLite() {
let path = FileManager
.default
.urls(for: .applicationSupportDirectory, in: .userDomainMask)
.last?
.absoluteString
.replacingOccurrences(of: "file://", with: "")
.removingPercentEncoding
print(path ?? "Not found")
}
Solution #2 using NSPersistentContainer.defaultDirectoryURL():
func whereIsMySQLite() {
let path = NSPersistentContainer
.defaultDirectoryURL()
.absoluteString
.replacingOccurrences(of: "file://", with: "")
.removingPercentEncoding
print(path ?? "Not found")
}
Either whereIsMySQLite() will print the path which you can simply copy-paste on your Mac here:
Finder > Go > Go to folder
The folder where the db is stored has recently been changed and is not where you'd expect to find it. Here's what I used to solve this:
First add this code to your viewDidLoad or applicationDidFinishLaunching:
#if TARGET_IPHONE_SIMULATOR
// where are you?
NSLog(#"Documents Directory: %#", [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
#endif
Got this from here: where is the documents directory for the ios 8 simulator
This will reveal the actual location of your app in the console during runtime.
Then use the SQLiteBrowser to check the contents of your SQLite DB.
Worked like a charm for me ;)
As Far as macOS Sierra version 10.12.2 and Xcode 8 is concerned
The folder should be here:
/Users/$username$/Library/Developer/CoreSimulator/Devices/$DeviceID$/data/Containers/Data/Application/$ApplicationID$/Library/Application Support/xyz.sqlite
To get the device id - Open terminal and paste:
xcrun xctrace list devices
As said before, you can use the sqllite command line tool.
However, you can also set the debug flag, which will dump out all sql commands as they execute through core data.
Edit the scheme, and add this in the "Arguments Passed on Launch"
-com.apple.CoreData.SQLDebug 1
In Swift 3, you have the the NSPersistentContainer and you can retrieve the path from there like this:
persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
(Assuming you are only using one persistent store)
1) Get path of sql database of your simulator.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#", [paths objectAtIndex:0]);
2) Open Finder. Press Cmd+Shift+G. Paste something, that you got from paragraph 1. Ex:
/Users/USERNAME/Library/Developer/CoreSimulator/Devices/701BAC5F-2A42-49BA-B733-C39D563208D4/data/Containers/Data/Application/DCA9E9C7-5FEF-41EA-9255-6AE9A964053C/Documents
3) Download in AppStore programm like SQLPro.
4) Open file in folder with name "ProjectName.sqlite".
GOOD JOB! You will see something like this:
An easy and convenient way to locate the Core Data database and to view and analyse the content, is by using a tool like Core Data Lab.
More info here: https://betamagic.nl/products/coredatalab.html
Disclaimer: I'm the creator of this tool.
I found the best way to find and open the .sqlite database is use this script:
lsof -Fn -p $(pgrep YOUR_APP_NAME_HERE) | grep .sqlite$ | head -n1
For whatever reason, the output on my Mac always has an extra n character, so I had to copy and paste it to open command. Feel free to modify the above command if you've figured out the right command.
For the best SQLite browser, I'd recommend TablePlus.
Adopted from:
https://lukaszlawicki.pl/how-to-quickly-open-sqlite-database-on-ios-simulator/
Download the SQLite Browser from here.
Run your app in the Simulator. The app should be copied to a path on your Mac that looks like:
/Users/$your username$/Library/Application Support/iPhone Simulator/$your iphone simulator version$/Applications/
Once you locate your app, you have to dig deeper to find the sqlite db (It's usually under Documents).
An answer for a noobs as I was, I spent quite a lot of time in figuring it out.
Steps I followed are :
Open finder and Press Command(Windows) + Shift + G.
Go to the folder add ~/Library/Developer
Search for the DB name you've created as in my case it was my.db in SQLite.
Download and install DB browser for SQLite.
Click open database.
Now drag and drop the DB file from your finder.
Since no one has pointed out, how to get the sqlite DB from the physical device.
Here is how to get the application data:
Browse the files created on a device by the iOS application I'm developing, on workstation?
After opening the .xcappdata file (right click > Show Package Content), you will usually find the DB file at the AppData/Library/Application Support folder.
Surprised no one has mentioned this, but assuming your Core Data store is sqlite, you can do a quick & dirty dump of its contents with no 3rd party tools by doing this in Terminal:
$ sqlite3 <path-to-file.sqlite>
// Dump everything
sqlite> .dump
// Dump just one type
sqlite> .dump ZSOMETYPE
// ^D to exit
I wasn't able to find it in the iPhone Simulator folder.
Then I found out the folder by printing the doc path in log:
NSLog(#"The Path is %#",
[[[NSFileManager defaultManager] URLsForDirectory:
NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
and the path turns out be like this :
// /Users/<username>/Library/Developer/CoreSimulator/Devices/<app specific id>/data/Containers/Data/Application/<id>/Documents/coredata.sqlite
If you've already access to sqlite, shm and wal files then run the commands in the terminal to merge the WAL file into the sqlite file.
$ sqlite3 persistentStore
sqlite> PRAGMA wal_checkpoint;
Press control + d
After running the above commands you can see the data in your sqlite file.
Utility to copy sqlite files to your desktops (do change the desktop path and give the absolute path, the ~ symbol won't work.
For iOS 10.0+ you can use
persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
I have created the Utility function that copies the sqlite file to your desired location (works only for simulator).
You can use the utility it like
import CoreData
let appDelegate = UIApplication.shared.delegate as! AppDelegate
UTility.getSqliteTo(destinationPath: "/Users/inderkumarrathore/Desktop", persistentContainer: appDelegate.persistentContainer)
Here is definition of utility method for swift
/**
Copies the sqlite, wal and shm file to the destination folder. Don't forget to merge the wal file using the commands printed int the console.
#param destinationPath Path where sqlite files has to be copied
#param persistentContainer NSPersistentContainer
*/
public static func getSqliteTo(destinationPath: String, persistentContainer: NSPersistentContainer) {
let storeUrl = persistentContainer.persistentStoreCoordinator.persistentStores.first?.url
let sqliteFileName = storeUrl!.lastPathComponent
let walFileName = sqliteFileName + "-wal"
let shmFileName = sqliteFileName + "-shm"
//Add all file names in array
let fileArray = [sqliteFileName, walFileName, shmFileName]
let storeDir = storeUrl!.deletingLastPathComponent()
// Destination dir url, make sure file don't exists in that folder
let destDir = URL(fileURLWithPath: destinationPath, isDirectory: true)
do {
for fileName in fileArray {
let sourceUrl = storeDir.appendingPathComponent(fileName, isDirectory: false)
let destUrl = destDir.appendingPathComponent(fileName, isDirectory: false)
try FileManager.default.copyItem(at: sourceUrl, to: destUrl)
print("File: \(fileName) copied to path: \(destUrl.path)")
}
}
catch {
print("\(error)")
}
print("\n\n\n ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NOTE ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n")
print("In your terminal run the following commands to merge wal file. Otherwise you may see partial or no data in \(sqliteFileName) file")
print("\n-------------------------------------------------")
print("$ cd \(destDir.path)")
print("$ sqlite3 \(sqliteFileName)")
print("sqlite> PRAGMA wal_checkpoint;")
print("-------------------------------------------------\n")
print("Press control + d")
}
For objective-c
/**
Copies the sqlite, wal and shm file to the destination folder. Don't forget to merge the wal file using the commands printed int the console.
#param destinationPath Path where sqlite files has to be copied
#param persistentContainer NSPersistentContainer
*/
+ (void)copySqliteFileToDestination:(NSString *)destinationPath persistentContainer:(NSPersistentContainer *)persistentContainer {
NSError *error = nil;
NSURL *storeUrl = persistentContainer.persistentStoreCoordinator.persistentStores.firstObject.URL;
NSString * sqliteFileName = [storeUrl lastPathComponent];
NSString *walFileName = [sqliteFileName stringByAppendingString:#"-wal"];
NSString *shmFileName = [sqliteFileName stringByAppendingString:#"-shm"];
//Add all file names in array
NSArray *fileArray = #[sqliteFileName, walFileName, shmFileName];
// Store Directory
NSURL *storeDir = storeUrl.URLByDeletingLastPathComponent;
// Destination dir url, make sure file don't exists in that folder
NSURL *destDir = [NSURL fileURLWithPath:destinationPath isDirectory:YES];
for (NSString *fileName in fileArray) {
NSURL *sourceUrl = [storeDir URLByAppendingPathComponent:fileName isDirectory:NO];
NSURL *destUrl = [destDir URLByAppendingPathComponent:fileName isDirectory:NO];
[[NSFileManager defaultManager] copyItemAtURL:sourceUrl toURL:destUrl error:&error];
if (!error) {
RLog(#"File: %# copied to path: %#", fileName, [destUrl path]);
}
}
NSLog(#"\n\n\n ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NOTE ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n");
NSLog(#"In your terminal run the following commands to merge wal file. Otherwise you may see partial or no data in %# file", sqliteFileName);
NSLog(#"\n-------------------------------------------------");
NSLog(#"$ cd %#", destDir.path);
NSLog(#"$ sqlite3 %#", sqliteFileName);
NSLog(#"sqlite> PRAGMA wal_checkpoint;");
NSLog(#"-------------------------------------------------\n");
NSLog(#"Press control + d");
}
Just add in viewDidLoad:
debugPrint(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
Open Mac OS terminal and type the following commands
xcrun simctl get_app_container booted com.ondevtratech.PlannerCoreData
xcrun simctl get_app_container booted <bundle <>identifier>
To open a DB :
brew install --cask db-browser-for-sqlite
Open << App path: sql lite.app >> <<.sqlite DB path>>
For Example :
open -a /Applications/DB\ Browser\ for\ SQLite.app /DTMPlanner.sqlite
print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!")
Please add this line in applicationDidFinishLaunching of AppDelegate.
It will give us the path of Documents.
But database of core data is in ./Library/Application Support/ with the name projectname.sqlite.

NSBundle mainBundle pathForResource (maybe not the same problem)

Problem : [NSBundle mainBundle] pathForResource returns null (0x0)
I read a lot of posts on this topic, here is what I found:
Make sure the file you are trying to get a path to, is in the project. To check, look in the project file list for the file, if it is not there, drag and drop it in.
Check that the file your trying to load is being copied to the app. To do this, click on project under project files (blue bar with project name in it->Click on the target->Click on Build Phases->Click to expand the "copy Bundle Resources", and make sure your file is in it. If it is not, click the plus, and add it.
Make sure the case matches exactly. (aka - The simulator will work/the app will not problem) Make sure the case matches exactly, otherwise it will return nothing. To fix this, just rename it in the project, or use the right case in the source.
Project may be missing the media framework. To fix this click on your project menu -> click on the target -> click to expand "Link Binary With Libraries". Now select MediaPlayer.framework and build the code.
If all else fails, clean the project, and try again.
All this is checked/fixed, but not working. I had this working fine, and then I changed the video that I am showing in the app. Since i changed the file, it stopped working.
NSString *path = [[NSBundle mainBundle] pathForResource:#"multiplying" ofType:#"m4v"];
Q: why is it null? The file is case matched/typed correctly and is about 10 megs. (is the file too large?) Works fine in the simulator, and I can get the path to an image, a line above this one, with no error.
You say it's working in simulator and not working on device?
May be you should try to copy the file at first launch to one of the application sandbox folders and access it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathForTheFile= [documentsDirectory stringByAppendingPathComponent: #"multiplying.m4v"];

Resources