Where is my sqlite data stored in iOS simulator? - ios

I created an iPad app on xCode(using PhoneGap) with sqlite plugin, stored data, and then when I want to view the data I stored I couldn't find where I saved it. According to my online research, it should be under /Library/Developer/CoreSimulator/Device
However when I navigate to the /CoreSimulator file, I don't see a sub-folder "/Device", just "/Profiles/Runtimes"?
When I reopen the app and wanted to check my stored data I couldn't see them aswell.

let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let docsDir = dirPaths[0]
print(docsDir)
Get the path printed in the debugger, copy it, open finder and press Cmd+Shift+G. A dialog box of Go to folder will open and paste the path and hit enter. You will be navigated to that folder. All the documents created in your project will be present in that folder including the .sqlite file. Don't try to navigate to that folder manually. Chances are you are looking at the wrong folder.
Also don't worry when every time Xcode prints a different path. Its a change brought from Xcode 6 onwards. Don't know why. But your files(those documents) will probably stay updated.

This is My app's folder:
/Users/***/Library/Developer/CoreSimulator/Devices/4420949E-AD14-4A4F-9153-53891734BEB9/data/Containers/Data/Application/0A18183F-2CF6-4D72-938D-DF59CFA48CCF
you can find your app's folder by the following code:
NSString *strPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
Or just add a plugin: NCSimulatorPlugin

I have the same issue when using core data,
Some how i solve the problem with following steps:
print the url of my sqlite file in console
copy the url
open a finder and press cmd + shift + G
paste the url and press enter
Then the sql file will be showed.
I haven't use PhoneGap, but if you can print the sql file url from SDK ,
you can find the file as well.

Standalone app
As of Swift 4+, add a breakpoint somewhere to stop your code, then in the console:
po FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!
You can then find an sqlite file in one of the subdirectories. It can be different, depending on iOS versions.
If you are using an App Group (or alternate method for standalone app)
If data is shared among multiple apps, the method above will not work. But you can also follow this method if you just did not find the sqlite file.
You can get Xcode to print the path:
Open Product > Scheme > Edit Scheme > Run > Arguments
Add -com.apple.CoreData.SQLDebug 1 argument in "Arguments Passed on launch"
Next time you launch the app, you should see something like this in the log output:
CoreData: annotation: Connecting to sqlite database file at /Users/***/Library/Developer/CoreSimulator/Devices/****/data/Containers/****/YourAppName.sqlite
As a bonus, you'll also get a bunch of other Core Data debug info.

If you don't want to (or can't) print the app's directory, you can do a simple search in Finder.
In Finder, open this folder:
/Users/{yourUsername}/Library/Developer/CoreSimulator/Devices
If you know the name of your database, use Finder's search to search for the database's filename.
OR
If you don't know the name of the database, use Finder's search to search for "LocalDatabase". There might be several "LocalDatabase" directories that appear in the search results, but if you look through them you should be able to narrow it down to the database you're looking for by its last modified date.

On your app's console type "po NSUserDirectory" it will return the url where all your simulator files are sitting.
1.copy that url.
2.on your machine goto "Go to folder" paste the url.
3.Library > Application support
That is where your sql file is sitting.
Hope it helps!

To be precise, you can find local db in this path.
/Users/jacob/Library/Developer/CoreSimulator/Devices/BBD9ED33-F903-4349-BB7F-A5A6F89DACC8/data/Containers/Data/Application/CF308117-7C0E-4A77-872F-93A02EA76F5F/Library/LocalDatabase
Where, BBD9ED33-F903-4349-BB7F-A5A6F89DACC8 and CF308117-7C0E-4A77-872F-93A02EA76F5F can be changed.

The accepted answer and other answers doesn't account for AppGroups. The easiest way to find the exact location is to get the defaultDirectoryURL() from your NSPersistentContainer.
You can check the documentation here.
Points to note:
This is a class func and can be overridden by a subclass. So make sure to call this on subclass if your app is using one.
This method returns the exact location for each platform.

Related

How can I access the contents of a folder selected from Files app?

Basically my app works like a iCloud-based note app (for example, logseq). Users first select a folder in Files app, then my app starts downloading/updating the contents of the folder.
So I implemented folder selection via UIDocumentPickerViewController, after I got the folder path in Files app. I tried downloading a hardcoded file like (<the folder path user just selected>/fileList.json) via FileManager.startDownloadingUbiquitousItem, got 257 permission error (the file does exist in my icloud drive). Then I followed the answer from this answer to call startAccessingSecurityScopedResource. It always returns false and the same 257 error returned.
Perhaps, I cannot access a random file from a selected folder? but how can those note apps work by simply letting users selecting a root folder?
Answering my own question after some debugging. Call startAccessingSecurityScopedResource on the folder path you grabbed from picker, not its subfiles. After that, you can start downloading its subfiles via startDownloadingUbiquitousItem

Where can I find the xcresult logs from my application in an Xcode UI Test?

On running a UI Test, I can see the .xcresult file generated in ~/Library/Developer/Xcode/DerivedData. I have some NSLogs in my application that I need to display as well. Does anyone know where is the path to get the application log or xcresult file?
The path your Xcode project's xcresult files as of Xcode 14.1 is
/Users/USER_NAME/Library/Developer/Xcode/DerivedData/APPNAME-SOME_XCODE_ID/Logs/Test/Test-SCHEME_NAME-DATE.xcresult
So if your username is gran_profaci, your app name is MyAwesomeApp, your scheme name is AwesomeScheme and you live in timezone UTC-5 your path would look something like this:
/Users/gran_profaci/Library/Developer/Xcode/DerivedData/MyAwesomeApp-aiupaskztadstnnevejnfigoiug/Logs/Test/Test-AwesomeScheme-2022.11.21_09-39-19--0500.xcresult
Each test you run will create a new xcresult file with the corresponding parameters and current date.
You can directly open the DerivedData folder from Xcode by clicking on the icon displaying a right arrow inside a circle:
If you want to extract information you can use the xcparse command line tool, in your example to export the logs:
xcparse logs /path/to/Test.xcresult /path/to/exportLogFiles
the path most likely appears on the terminal
/Users//Documents/P/ios/build/<>/Logs/Test/Run-<.....>.xcresult

What happens to local files on iOS when the app is updated?

My iOS app is writing to local files to:
/var/mobile/Containers/Data/Application/A.../Library/a.txt
When my app updates, it gets a new application container ID and folder:
/var/mobile/Containers/Data/Application/B...
What happens to all the files I wrote to container ID A?
Is there an "update hook" that will allow me to copy all the "A" container files to path "B"?
Can the new version of the app (B) read the old versions files (A)?
Is there any documentation around what happens to the filesystem during updates?
Is it possible to recover files from container A after B has been installed?
When you update an app, by changing its version number in the .plist file, iOS creates a new directory for that app with a different hexadecimal name and it copies all the files to the new directories. Now if you are using the absolute paths to get the details of files from the directories then those paths would be incorrect and you won't get the file details.
I just tried this in simulator. I created a function as below which will return the document directory path url
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
I called this function from didFinishLaunchingWithOptions in app delegate when version number was 1.0 and it returned the below path :
file:///Users/BhargavRathod/Library/Developer/CoreSimulator/Devices/3082611F-BCCA-4D17-B390-E0EF4CA454DA/data/Containers/Data/Application/72759097-38F3-4292-825E-1D2343219973/Documents/
When I updated the version number to 1.1 it returned me the new path as :
file:///Users/BhargavRathod/Library/Developer/CoreSimulator/Devices/3082611F-BCCA-4D17-B390-E0EF4CA454DA/data/Containers/Data/Application/72DC31E9-C32F-42CC-8449-F1946ADB1018/Documents/
So if you are using a absolute path to access any file from document directory then it is not good practice. You can just save the file name(or relative path after the document directory) and whenever the access to that file name is required then get the file name and append it after the document directory path and access the file.
I hope this will be of some help to you.
My iOS app is writing to local files to: /var/mobile/Containers/Data/Application/A.../Library/a.txt
Okay, stop right there. This is wrong.
Your app has its own sandbox. This sandbox persists forever, thru updates, as long as your app keeps its Bundle ID, and as long as the user does not delete the app.
You thus have no business knowing or thinking about the full absolute path to where your file is. All you know, and all you need to know, is that it is in your app’s sandbox in the Library directory. You can, at any time, obtain the URL of the Library directory by means of its search path:
https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/librarydirectory
And that is where the file will always be. As long as you ask the FileManager for your Library directory and for the a.txt file within it, you will find the same file, regardless of any updates, as long as the user doesn’t actually delete your app (because that deletes the sandbox).
Can explain what happens to the files
Nothing. They stay where they are within the sandbox. The absolute URL of the sandbox may change, but your files are unaffected.
how to keep the files written by the previous version of the app
They are kept automatically. You don’t have to do anything.
(Having said all that, keep in mind that if you submit an app with a different bundle id, that is not a new version of your app. It is a totally different app. In that case you would have a very different problem to solve. This would be no different from any other problem of communicating files from one app to another. You’d need to put the files in a common location, make them available thru the Document Browser, make them exportable by the user, or whatever.)

iCloud Drive cannot remove file created from other device

I'm trying to adopt iCloud Drive to store backups of the data of my application using a single file for each backup, if it's relevant they're simple XML files with a custom extension. File creation and upload are working fine but as I'm now trying to let the user manually delete backups I found out that I cannot delete the file programmatically but I can do it if I go to iCloud Drive from the app on iOS or the folder in Finder on macOS.
To save the files I first retrieve the root for the container with
FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
and create the Document folder if it doesn't exists as I want the user to be able to view and edit the files, after creating the file locally in the temporary directory I upload it with
let file = FileManager.default
if file.fileExists(atPath: remotePath.path) {
try? file.removeItem(at: remotePath)
}
try? file.setUbiquitous(true, itemAt: localPath, destinationURL: remotePath)
where remotePath is the path retrieved before with the file name appended. To load the files I use a NSMetadataQuery and get the path of each file with NSMetadataItemURLKey on each returned item, which is working fine but when I attempt to
try? FileManager.default.removeItem(at: retrievedPath)
it works if the same device created the file but if it is from another one it always fail and the error says that the file does not exists at the specified path.
I've removed error handling code for clarity but I've tested this behaviour inspecting the thrown error.
How can I delete any file even from other devices, am I missing some steps?
I was indeed missing something, after reading this question, in particular this answer, I found out that even if the NSMetadataQuery returns the path correctly is possible that the file has not been downloaded to the the device, hence the error.
To correctly delete a file you have to mimic the behaviour of UIDocument and use a NSFileCoordinator on a background queue, refer to the answer referenced before for implementation details.

NULL when using fopen with xcode

I am trying to initialize a multidimensional array from a file using C for a iPhone 4inch app but I can't open up the file using fopen.
Whenever I try this I get a NULL:
FILE *f;
f=fopen("/level1.rez", "r");
if (f == NULL)
{
printf("Error Reading File\n");
//exit (0);
}
I am not sure how to open files using C.
I tried this already:
I printed out the current working directory using getcwd but all I got was "/" and when I attached that to the file name I still got NULL.
I read that if you go to product > scheme > edit scheme then options you can change the current working directory but I don't see that option.
Also I read that you can use absolute paths like: /users/name/desktop/program
but I am new to iOS development so I don't know if that is a good idea.
So how do I get fopen to work?
You CAN specify absolute paths in iOS, but the path in your example is probably used in Mac OS, which is laid out a little differently. You can specify paths to fopen() as you say, but there is more work to finding out what the first part of that path really is.
The iOS puts all AppStore apps into folders with randomly generated sandbox directory names. It is basically the the hexadecimal string of a GUID. So you need to use methods from iOS frameworks to get the first part of the path (or URL) to your file.
If the file is part of the app bundle so it can ship with the app, then you will need to use NSBundle methods to find the path to the file.
If the file is generated or downloaded after the app starts up on the device, then you need to use NSFileManager methods to determine the path to the directory of the file. (Typically the Documents directory. You can build a directory structure of your choice within the sandbox.)

Resources