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.
Related
Using FileManager.moveItem I can move a file in iCloud to another location in iCloud without downloading it locally. I would like to perform the same thing but with FileManager.copyItem, in the sense that I would like to make copies of files within iCloud without downloading them locally.
With FileManager.copyItem it seems to not be possible.
Moreover, analysing the .js of icloud.com/iclouddrive I see /moveItems and other endpoints, but no /copyItems. There is however, a "DuplicateItems" string in a "transactionType" array, but I cannot understand how to use it.
Currently i was saving my application data (Media) to the CacheDirectory i.e
/var/mobile/Applications/BEAFC76C-C450-4A3A-9765-A0385A9580F3/Library/Caches
and things were going fine. But recently i got a bug report that the application data has been deleted. When i searched over it, i got this Apple Doc. According to it, DocumentsDirectory should be the ideal place to store the User/Application data.
Put user data in the /Documents/. User data is any
data that cannot be recreated by your app, such as user documents and
other user-generated content.
And Cache should not be used to store the User Data that could not be reproduced by the application.
Put data cache files in the /Library/Caches
directory. Examples of files you should put in this directory include
(but are not limited to) database cache files and downloadable
content, such as that used by magazine, newspaper, and map apps. Your
app should be able to gracefully handle situations where cached data
is deleted by the system to free up disk space.
What should be the ideal place to store it.
EDIT:
I have an application that allows user to store Videos and Photos in the application. For that i used CacheDirectory. But i am getting bug reports that the Data (Videos/Photos) is getting deleted. What conclusion i draw is that the data is being getting delete by the Device itself in order to provide space.
Secondly i also wanna give the iTunes sharing function. So only the particular files has to be stored in the DocumentsDirectory. Some files can never be exposed and some has has to be shared. What should be the ideal way to store the files.
Use Documents (NSDocumentDirectory) for files you wish to share via iTunes.
Use Application Support (NSApplicationSupportDirectory) for files you wish to hide from the user but still be backed up and never deleted by the OS.
Starting iOS 5, Apple says that it's no longer a good thing to save all kind of files in Documents Directory - if you do that, your app will be rejected for sure because this folder is backed up to iTunes & iCloud, unless otherwise specified.
It says that we should save files into Caches or Tmp Directory - these won't be backed up, but it's not a good thing to do because files from these directories can disappear if low memory happens.
So I think the best think to do is to save the important files that you need all the time in your app into Documents Directory and mark them not to be backed up, like this.
Library/Application Support Folder is the folder you should be using.
This directory doesn't always exist, and thus you may need to create it.
You can enable or disable whether you want to backup this data with iTunes or not.
This data is not accessible even if you enable file sharing. Only data that you put in Document directory would be shared with iTunes sharing, so you can still protect your data and get it backed up as well. Apple's documentation
I've read the Apple docs and Ray Wenderlich's tutorial. It seems that I'm forced to use UIDocument so I read it up in the docs. I've found that it's effective to use Document-based approach.
My problem is I don't want to be tied in techniques specific to the platform (iOS) thus my app has its own models made from scratch that only inherit from NSObject. This includes saving/loading.
Now, I need to integrate iCloud along with my old models. How will I do it in an elegant/effective way where I get to keep my old model implementation and be able to integrate iCloud?
You are not in any way forced to use UIDocument. You can use iCloud via NSFileManager and NSMetadataQuery. The general approach is:
When creating files
Create the file locally, as normal without iCloud
Use -[NSFileManager setUbiquitous:itemAtURL:destinationURL:error:] to transfer the file to iCloud storage.
(if necessary) Check on upload progress using NSMetadataQuery or by polling URL resource values.
When opening files
Use NSMetadataQuery to locate iCloud-resident files
Use -[NSFileManager startDownloadingUbiquitousItemAtURL:error:] to begin download or to synchronize the local copy with the cloud copy.
Check on upload progress using NSMetadataQuery or by polling URL resource values with [NSURL resourceValuesForKeys:].
When editing files
Use NSFileCoordinator to coordinate your file access with the ubiquity daemon.
Use NSFilePresenter to get notifications of changes to files.
This is all covered in sessions from WWDC 2012 (and maybe 2011, I don't recall), and the classes and methods you'll need are all in the iOS documentation.
I am trying to code a hard disk based restore function into an existing demo Photo Application for iOS devices. The idea is to allow users to restore the last applied effects and all, even after restarting the application/unexpected crash etc.
I am saving one image file (the latest effects applied to it) into the NSCachesDirectory:
NSData* data = UIImagePNGRepresentation(image);
[data writeToFile:[self getFileAtIndex:getPath] atomically:YES];
On going to the recover option, the file saved at this path is recovered using:
image = [[UIImage imageWithContentsOfFile:[self getFileAtIndex:getPath]]retain];
The code is working fine in my test device (iPhone 4s). But somehow I doubt if this is the best practice for coding a restore function.
Moving into a real world app, if things were stored in NSCachesDirectory, do you think it will be backed up into iCloud? Is there any possibility of a conflict with other apps?
How exactly is NSCachesDirectory directory managed for multiple apps accessing it simultaneously?
I would like to know the best practice for doing this.
Please help/comment.
As Mr. Bonjour mentioned in the comment, on iOS, every app has its separate file system, so there can never be any conflict with other apps.
Caches directory is not backed up on iCloud and you shouldn't rely on files in caches directory to persist across launches. You should use caches directory for temporary files only. If you allow restore only during one session, then using caches directory is fine, but if you want to allow restore across multiple launches, you should store them in library/documents directory. But be aware that Apple has a strict review policy for storing files in Documents directory since it takes up space on user's cloud storage.
I have a quite simple shoebox-style iOS app with 1 single Core Data database (as a UIManagedDocument) and thought about trying to add iCloud support.
I of course have to check if there is already an existing database in the cloud *before creating a new UIManagedDocument at startup*, saving/opening it, etc.
As i already know the filename and that there's either 1 document or no document at all, I didn't really get if I had to
start a NSMetaDataQuery with a predicate for the exact filename
and then get the fileURL from the result (and download it
explicitly?) and open it if there is one, or
just use [[NSFileManager defaultManager] fileExistsAtPath:self.iCloudDBURL]
with iCloudDBURL created from URLForUbiquityContainerIdentifier + appending ? Is this URL only a local one and doesn't check the "real" cloud automatically?
I know the use of UIManagedDocument might not be the "right" way for this kind of app, but I thought it'd easier and I could try..
You need to use the NSMetadataQuery approach.
When using iOS on iCloud, documents don't download automatically-- they only download when you ask for them. Using NSFileManager as you suggest would only tell you if the file existed on the local device. But, the file might exist up in the cloud, not downloaded locally yet. If you use NSMetadataQuery you can find out if the document exists anywhere, even if it's in the cloud and not actually downloaded yet. You can find out about the document if it was created on a different device. This also covers the case where the user deletes and reinstalls the app, but doesn't delete cloud data-- you find out if it exists even though it's not downloaded.
Since you're using UIManagedDocument you shouldn't need to make a specific download call-- it will handle that for you when you open it.