I'm migrating an app built with the Dropbox v1 API to the v2 API. The app needs to sync files in source dropbox folder to app documents folder. The current version of the app uses the clientMTime to skip syncing files which have not changed. With v1, I got the required info--specifically the path and clientMTime of each file in the Dropbox folder--by doing this...
// ==============================================================
// getDBMetadata
// ==============================================================
- (void)getDBMetadata
{
NSString* theOPMLFilesRoot = #"/";
[self.restClient loadMetadata:theOPMLFilesRoot withHash:self.opmlFilesHash];
}
// ==============================================================
// restClient:loadedMetadata:
// ==============================================================
- (void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata
{
self.opmlFilesHash = metadata.hash; // Used to check for changes
for (DBMetadata* __unused theMetadata in metadata.contents) {
LogDebug(#"Path: %#, clientMtime: %#.", theMetadata.path , [theMetadata.clientMtime toStr]);
}
[self synchronizeFilesUsingDBMetadata:metadata];
}
The v2 iOS API docs for Dropbox object 'DBFILESMetadata' include 'path' but do not list clientMtime as an included property (which they're calling 'field'). Is there a way to get clientMTime with v2?
The DBFILESMetadata can represent a file, folder, or deleted item. Only files have a client modified time though, so clientModified is only available on DBFILESFileMetadata, which represents a file only.
DBFILESFileMetadata is a subclass of DBFILESMetadata. To check if a particular DBFILESMetadata is a DBFILESFileMetadata, you can use isKindOfClass as shown here. You can then cast it to the relevant subclass.
Also, note that rev or contentHash are better options for checking if the file has changed.
Related
I am trying to transition from Dropbox API v1 to v2. My objective is to upload video files to Dropbox in the app folder that Dropbox creates for the apps that do not require access to root folder. I checked this tutorial but have the following confusions:
NSData *fileData = [#"file data example" dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
// For overriding on upload
DBFILESWriteMode *mode = [[DBFILESWriteMode alloc] initWithOverwrite];
[[[client.filesRoutes uploadData:#"/test/path/in/Dropbox/account/my_output.txt"
mode:mode
autorename:#(YES)
clientModified:nil
mute:#(NO)
inputData:fileData]
setResponseBlock:^(DBFILESFileMetadata *result, DBFILESUploadError *routeError, DBRequestError *networkError) {
if (result) {
NSLog(#"%#\n", result);
} else {
NSLog(#"%#\n%#\n", routeError, networkError);
}
}] setProgressBlock:^(int64_t bytesUploaded, int64_t totalBytesUploaded, int64_t totalBytesExpectedToUploaded) {
NSLog(#"\n%lld\n%lld\n%lld\n", bytesUploaded, totalBytesUploaded, totalBytesExpectedToUploaded);
}];
What should be "/test/path/in/Dropbox/account/my_output.txt" in my case, as I do not access the root folder?
Whether the same code is supposed to work for binary files such as mp4 files (it uses UTF8 encoding in the sample code when preparing NSData)?
The "/test/path/in/Dropbox/account/my_output.txt" in the sample is just an example. You should supply the path for the desired location of the uploaded file in the Dropbox account. If you're using an app folder app, the root you supply will automatically be translated into the app folder itself. For example, if you have an app folder at "/Apps/MyAppName", and you want to upload a file named "video.mp4" into a folder called "Videos" in your app folder, you should supply a path value of "/Videos/video.mp4". That will automatically become /Apps/MyAppName/Videos/video.mp4 in the account.
The sample makes an NSData by encoding a string, but you can use the same uploadData to upload a file from any NSData.
Basically this path is /test/path/in/Dropbox/account/my_output.txt.
In dropbox account it will create folders like this test>path>in>Dropbox>account-- then your file will be in account folder. You can replace it with
/yourFolderName/Yourfilename.extension
I was found something strange when I using Dropbox SDK 1.3.14
And here is how the bug happen , I put a dictionary tree like
/Comic/Author - Comic name (ex.浦澤直樹 - Monster)/Volume1/0.jpg , 1.jpg , ...)
And I want download the jpg to iOS app,And also create the same dictionary tree as Dropbox
So I create a dictionary tree in Document , It looks like
/var/mobile/Containers/Data/Application/12711FE6...290C7EAF50/Documents/Dropbox/Comic/浦澤直樹 - Monster/Volume1
Than I try to download the first page of comic
But it shows an error tell me the dictionary is not exist .
I use NSFileManager to check , It did exist .
Finally I find the problem
At this callback
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
for (DBMetadata *file in metadata.contents) {
NSLog(#"File Path : %#",file.path);
}
}
Path will print like this
1./Comic
2./Comic/浦澤直樹 - Monster
3./Comic/浦澤直樹 - Monster/Volume1
4./Comic/浦澤直樹 - monster/Volume1/0.jpg
Now at the last file path , it gives me a different path name
I don't know why , but if I use this path to check is the parent dictionary is ready , It will return false.
So I never can download the file to specified path success
I was wonder does anyone got same issue like me ?
Dropbox itself is case-insensitive, with attempts to be case-preserving. However, due to various specifics, the API can't always return the expected case for every path component. So, for any file or folder metadata, the filename/last path component should have the preserved case, but other path components are not guaranteed to.
We realize this is non-ideal of course and are looking into ways to improve it, but I don't have a solution to offer right now.
If you need the preserved casing, you'll need to build it up from the last component in each parent entry.
I have an app that creates tickets by putting a file in a Dropbox folder. Based on this ticket a file is added to another (Dropbox) folder. I use the Dropbox Core API.
Now, I have to refresh the folder manually to see if the new file already has been added.
I am searching for a method to be notified when the folder is changed (a file has been added) but haven't found it. I guess longpoll_delta can do the job but that isn't available in the iOS API.
Is there a method to do this in Objective-c?
I retrieve the data the following way:
- (void) refreshTable {
[self.restClient loadMetadata:#"path"];
}
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
for (DBMetadata * child in metadata.contents) {
if (!child.isDirectory && !child.isDeleted) {
NSLog(#"Filename: %#", child.filename);
}
}
}
Any ideas?
The new Dropbox API v2 has function for this:
[[[dropboxClient.filesRoutes listFolderLongpoll:cursor] setResponseBlock:...];
Cursor parameter is returned by listFolder or listFolderContinue.
Im trying to overwrite an uploaded file to Dropbox.
Instead of replacing the file, Dropbox keeps adding another conflicted copy,
I have got the metadata for the file using
for (DBMetadata *file in metadata.contents) {
NSLog(#" %# metadata %#", file.filename,file.rev);
}
prints myFile.sqlite metatdata 5372f37f73G
Im uploading the file with:
[restClient uploadFile:#"myFile.sqlite" toPath:#"/Data" withParentRev:#"5372f37f73G" fromPath:filePath];
checked How to overwrite file with parent rev using Dropbox API in iOS?
How to avoid "conflicted copy" when uploading to dropbox from iOS client
dropbox keeps creating conflicted copies ios sdk (core api)
What am I missing here?
I was calling the wrong folder for meta data in - (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
For anyone else
//Calls all files for your app folder
[self.restClient loadMetadata:#"/"];
//Calls a folder you created within your app folder
[self.restClient loadMetadata:#"/yourfolder"];
Hi all I am developing an application that brings up the entire folder and file structure from any content management system for now I have done Box and sharepoint integration. I am looking to sync dropbox now. In the DBMetaData class I have properties
BOOL thumbnailExists;
NSArray* contents;
NSString* icon;
First thing I want to do here is that I want to load thumbnails of files, I do not get one thing the icon property returns a string, like this 'page_white_acrobat' (I thought it would return a url or something where I could download the thubmnail). Is there any way to bring thumbnails using the dropbox sdk. Also I uploaded a .mp4 file and .png file, they show up thumbnails when I open dropbox in chrome but in the SDK the thumbnailExists property returns NO.
Second I want the number of sub folders and the files for a folder, I tried accessing the contents property of a folder DBMetaData Object and it returned nil. Is there any way in the SDK to count the number of files inside a folder or any work around.
It seems that Dropbox just provides the name of the icon they use. You can't download it, so you should check this string and use resources in your app bundle.
The contents of a DBMetadata object will be null until you actually make a request to load metadata at that path.
This code will get you started with subdirectories.
-(void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata
{
// LOAD METADATA OF SUBDIRECTORIES
for (DBMetadata *node in metadata.contents) {
if (node.isDirectory) {
[_restClient loadMetadata: node.path];
}
}
// GET COUNT OF DIRECTORY CONTENTS
if (metadata.isDirectory) {
NSLog(#"%# contains %d files and folders", metadata.path, metadata.contents.count);
}
}
To list the contents of a path or directory, you need to call the following method of your DBRestClient object:
- (void)loadMetadata:(NSString*)path;
which then invokes the following delegate callback(please see the method body for code to download the thumbnail for each file in the listed directory):
- (void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata
{
for (DBMetadata *file in metadata.contents)
{
// 1. Use the DBMetadata * file object to do things like: add a table-view cell for the file.
[self.filesListView addCellForFile: file];
// 2. Request thumbnail for each file
NSString *localThumbnailPath = [self localThumbnailPathForFile: file]; // create a local-file-path for the thumbnail
[dbRestClient loadThumbnail: file.path ofSize:#"l" intoPath:localThumbnailPath];
}
}
In the method above, the loadThumbnail:ofSize:intoPath: method will result in invoking the following delegate callback:
- (void)restClient:(DBRestClient*)client loadedThumbnail:(NSString*)localPath
from which, you must use the given localPath to update your UI with the downloaded thumbnail.