Basically, I have 2 projects running, one is in obj-c and another is in Swift 4 and I want them to access their directory folder in order to exchange their resources in the run-time. Right now my approach is accessing document directory of Swift 4 project via:
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
so it will generate the path like:
/Users/public1/Library/Developer/CoreSimulator/Devices/22D423BD-C28D-45B7-A976-D9FB02409988/data/Containers/Data/Application/3B15E00A-910B-420E-8047-99F2E6E5013D/Documents
And if I want get the same Documents directory of obj-c project, I will use above path, delete 2 last components path:
/Users/public1/Library/Developer/CoreSimulator/Devices/22D423BD-C28D-45B7-A976-D9FB02409988/data/Containers/Data/Application
then using enumerator.nextObject() to find the flag of obj-c project. It works perfectly fine in simulator but in the device, those code counters a problem is that when running on a device, those folders won't be on the macOS folders but in device folders, so the URLs executes by above code is something like:
/var/mobile/Containers
and I neither can find nor access to that folder so that my enumerator won't work. So is there a way to accessing that folder (using code) or some mechanism to get 2 project folder shared with each other?
=========================================================
EDIT: for using AppGroup I added those code in my Obj-C project:
NSUserDefaults *pathShared = [[NSUserDefaults alloc] nitWithSuiteName:#"com.example.myDomain"];
[pathShared setObject:directoryPath forKey:#"path"];
and in Swift 4 code:
let userDefault = UserDefaults(suiteName: "com.example.myDomain");
let path = userDefault?.object(forKey: "path");
but it didn't seem to work...
A language that you are using to implement application is not a reason. It is just a different applications with different sandboxes. In iOS one application can't get access to files from a sandbox of other application. You can share data between applications by using same AppGroup for the applications, after that you can use shared UserDefaults and write and read files from a shared directory:
<...>
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: #"com.example.domain.MyShareExtension"];
[mySharedDefaults setObject:theAccountName forKey:#"lastAccountName"];
<...>
NSFileManager* fileManager = [[NSFileManager defaultManger];
NSURL* url = [fileManager containerURLForSecurityApplicationGroupIdentifier:[self appContainerName];
<...>
On iOS, the sandbox will prevent your app from accessing any other app's data, even if you developed the other app yourself, too. However, you can set up an App Group and entitle both of your apps to access it, and that will allow you to share what you want. The Sharing Data with Your Containing App heading on this page has a good overview on how to do that
Related
I enabled UIFilesharingEnabled option in my app set to true but this was exposes my documents file and my sqlite.db file also.
Then how can restrict on to display/access my database files to user or other apps?
You should take a look at the Library Directory section Apple File System Basics. There you can find all information regarding where to write your app files:
Library
This is the top-level directory for any files that are not user data
files. You typically put files in one of several standard
subdirectories. iOS apps commonly use the Application Support and
Caches subdirectories; however, you can create custom subdirectories.
Use the Library subdirectories for any files you don’t want exposed to
the user. Your app should not use these directories for user data
files. The contents of the Library directory (with the exception of
the Caches subdirectory) are backed up by iTunes and iCloud. For
additional information about the Library directory and its commonly
used subdirectories, see The Library Directory Stores App-Specific
Files.
You can check this post how to access the Library directory in your App Bundle
It could be achieved by using libraryDirectory.
private static var __once: NSString = {
let documentFolderPath = NSSearchPathForDirectoriesInDomains(
.libraryDirectory,
.userDomainMask,
true)[0] as String
let databaseFile = "DATABASE_FILE_NAME"
return "\(documentFolderPath)\(databaseFile)" as NSString
}()
I'd like to use Files.app to copy a folder (e.g. from Dropbox or iCloud), then switch to my App and read the contents of this folder for further processing. I can't find a way though to get the actual data from UIPasteboard. Calling loadObject on the NSItemProvider gives me an NSData archive which I can unarchive and then get a (private) FPItem, which implements <NSFileProviderItem>, but what now? How can I actually request downloading the actual folder this item points to?
I've used one of my precious Technical Support Incidents (TSI) to have an Apple engineer give a statement.
The outcome is that at this point of time, copy'n'paste of a folder in Files.app to your own app is not supported. If you want to import a folder, use a UIDocumentPickerViewController.
As I understand it, you would like to download a folder from Dropbox. You may want to consider using the Dropbox API with a URLSession.shared.datatask(...) using a REST request. If you don't want to deal with implementation details, you could use a library like SwiftyDropbox. There isn't really any need to use UIPasteboard because your end goal is downloading a folder to your app. If you would like to save said folder to the Files app, you can do so after you download/process the folder.
Here are some useful links:
Swifty Dropbox Overview
Swifty Dropbox Download Example
Swifty Dropbox API Docs
Dropbox API HTTP (RESTful Requests)
In link 2, the snippet of code below gets the directory to save the file in. One way you could get a whole folder is to (1) create a new folder in the Documents directory like this and (2) iterate through every item in the Dropbox folder and add that to the newly created folder.
let fileManager = FileManager.default
let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let destURL = directoryURL.appendingPathComponent("myTestFile")
To implement (1), you would need to get all the files in a folder, which you can do with this /list_folder API endpoint. Then, to implement (2), you would iterate through all the files given, downloading them like in link 2.
Let me know if my answer helped, or if you need any further clarification. Thanks a bunch! :)
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.
After reading Apple documentation, I used URLsForDirectory to obtain the Library destination within my app, and my objective is to download content from a hosted service & cache it in the Library folder, so that User cannot interact with the contents through iTunes.
NSArray *docPaths= [[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask];
NSLog(#"%#",[docPaths description]);
NSString *docPath=[(NSURL *)[docPaths objectAtIndex:0] path];
docPath = [docPath stringByAppendingPathComponent:#"audios"];
Running & executing the code several times(various simulators, and iOS 8.0 device) I realized that somehow the content being fetched seems to be no longer accessible, so I logged the library destination path, and after running app every time the destination path seems to have changed:
/var/mobile/Containers/Data/Application/83725F33-C7EA-4F89-B69F-0AECF26FA77A/Library/"
/var/mobile/Containers/Data/Application/4627FC86-C3A4-4A1A-9721-AF73D808433E/Library/"
/var/mobile/Containers/Data/Application/709CCA84-936A-4596-933A-D6779758FF85/Library/
Has anybody faced a similar issue? If so how did it got corrected? And is there anything I've missed out here?
I had the same issue. I think the variable part changes only when the code is recompiled (ie not if you just rerun without making changes), so should not affect a live app. But I decided in the end not to save the path - just to use the same code (as you use above) both when saving and retrieving the data. It seems to work, in spite of the fact that the path actually changes between runs (so the simulator must copy the files across, or rename the folder).
Does the Dropbox Sync API allow for copying directories or files from Dropbox into the app sandbox directories?
I was excited to use the Dropbox Sync API and use Dropbox to manage media assets between my OS X machine and an iPad running my app.
I integrated the Sync API pretty quickly and am able to open files and save them in to Dropbox again.
Because my app is already set up with many many calls to dynamically load media assets, it would add unnecessary complexity to try to open all those assets from the Dropbox filesystem. My intention was to use the Sync API to determine if there are updated assets and then copy them in to one of my application directories.
But it seems that nearly all the objects returned using the Sync API are DBObjects, and I can't perform normal NSFilesystem file operations such as copy. Also the DBObjects seem to have no copy functions themselves.
Is there any way to do this without resorting to the CorecAPI?
Example, for an arbitrary file type called story
//get a list of stories and put them in an array
DBPath *storyPathDB = [[DBPath root] childPath:#"/storyBundlesDB"];
NSArray *listOfStoriesDB = [[DBFilesystem sharedFilesystem] listFolder:storyPathDB error:nil];
for (DBFileInfo *story in listOfStoriesDB)
{
//now I can list out the path of my stories, but that's about it...
DBPath *storyPath = story.path;
NSLog(#"%#",storyPath.stringValue);
//How can I treat these stories whether they are directories or .mov, .png, and copy them to my app directory?
}
I saw this question here Data syncing with DropBox API and iOS where people suggested using the SyncAPI for exactly this purpose, but it seems as if noone on that thread had actually tried it.
You could use readData to read the contents of the file and then write it to another location, if you can't directly use the DBFile objects.
Note that if you want to get notifications when a file (in Dropbox) changes, you'll need to hold that file open. Essentially, files are only updated when you hold the file open, get a notification that there's newer content available, and then call update.