老的Dropbox SDK从去年就废弃不能用了,公司的App一直没有修改,所以相关功能一直不能使用,最近恰好交由我完成该功能,在此记录一下Dropbox API v2集成过程。
1.创建账号:
- 进入官网:https://www.dropbox.com
- 注册Dropbox账号,然后创建app,按照下图选择即可:
- 创建好后,就可以获得
App key
和App secret
了
注:
可以看到,刚创建的App的status是Development
,点击Apply for production后会进入review流程,review通过后,会变为Production
状态。
但是:
此时提交review后Dropbox官方并不会立刻审核,Development
状态下可以最多供500人使用,如果超过了500人,这时Dropbox官方才会review你的App,具体说明见:https://www.dropbox.com/developers/prod_request/2747504
2.代码集成
- 进入Git:https://github.com/dropbox/dropbox-sdk-obj-c
- 按照相关步骤说明集成Dropbox SDK
注:
1 . Dropbox SDK需要在iOS9.0+系统上运行,如果你的app要兼容iOS9.0以下系统,请做好兼容处理,我遇到的兼容问题及解决方法见:https://www.jianshu.com/p/4f839b2d0445
2 . 官方文档中写的在使用CocoaPods集成时,Podfile里面这样写:pod 'ObjectiveDropboxOfficial'
;
此处建议修改为:pod 'ObjectiveDropboxOfficial', '~> 3.4.0'
原因:
pod 'ObjectiveDropboxOfficial'
这样写所引入的SDK版本是3.0.15,该版本中的下载文件API有问题,其源码和官方Demo中的代码不同,会导致下载文件失败。
改为pod 'ObjectiveDropboxOfficial', '~> 3.4.0'
后就可以了。
亲测有效!这个也是当时遇到的另一个坑。
3 . pod配置完成后,plist文件中需要加入以下两个key,否则运行会crash.
LSApplicationQueriesSchemes
dbapi-8-emm
dbapi-2
3.主要API说明
- 初始化
DBUserClient
:
#import //头文件
[DBClientsManager setupWithAppKey:@""];
- 授权认证:
[DBClientsManager authorizeFromController:[UIApplication sharedApplication]
controller:controller
openURL:^(NSURL *url) {
[[UIApplication sharedApplication] openURL:url];
}];
授权成功回调:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary *)options {
DBOAuthResult *authResult = [DBClientsManager handleRedirectURL:url];
if (authResult != nil) {
if ([authResult isSuccess]) {
NSLog(@"Success! User is logged into Dropbox.");
} else if ([authResult isCancel]) {
NSLog(@"Authorization flow was manually canceled by user!");
} else if ([authResult isError]) {
NSLog(@"Error: %@", authResult);
}
}
return NO;
}
说明:
如果你的app在这个回调中还有其他的处理,则需要根据sourceApplication来判断是哪一个回调来源,
Dropbox的sourceApplication 是 com.apple.SafariViewService
- 创建文件夹
DBUserClient *client = [DBClientsManager authorizedClient];
[[client.filesRoutes createFolder:@"/test/path/in/Dropbox/account"]
setResponseBlock:^(DBFILESFolderMetadata *result, DBFILESCreateFolderError *routeError, DBRequestError *networkError) {
if (result) {
NSLog(@"%@\n", result);
} else {
NSLog(@"%@\n%@\n", routeError, networkError);
}
}];
- 获取文件列表(列表文件多的话支持分段获取)
[[client.filesRoutes listFolder:@"/test/path/in/Dropbox/account"]
setResponseBlock:^(DBFILESListFolderResult *response, DBFILESListFolderError *routeError, DBRequestError *networkError) {
if (response) {
NSArray *entries = response.entries;
NSString *cursor = response.cursor;
BOOL hasMore = [response.hasMore boolValue];
[self printEntries:entries];
if (hasMore) {
NSLog(@"Folder is large enough where we need to call `listFolderContinue:`");
[self listFolderContinueWithClient:client cursor:cursor];
} else {
NSLog(@"List folder complete.");
}
} else {
NSLog(@"%@\n%@\n", routeError, networkError);
}
}];
- (void)listFolderContinueWithClient:(DBUserClient *)client cursor:(NSString *)cursor {
[[client.filesRoutes listFolderContinue:cursor]
setResponseBlock:^(DBFILESListFolderResult *response, DBFILESListFolderContinueError *routeError,
DBRequestError *networkError) {
if (response) {
NSArray *entries = response.entries;
NSString *cursor = response.cursor;
BOOL hasMore = [response.hasMore boolValue];
[self printEntries:entries];
if (hasMore) {
[self listFolderContinueWithClient:client cursor:cursor];
} else {
NSLog(@"List folder complete.");
}
} else {
NSLog(@"%@\n%@\n", routeError, networkError);
}
}];
}
- 文件下载
[[[client.filesRoutes downloadData:@"/test/path/in/Dropbox/account/my_file.txt"]
setResponseBlock:^(DBFILESFileMetadata *result, DBFILESDownloadError *routeError, DBRequestError *networkError,
NSData *fileContents) {
if (result) {
NSLog(@"%@\n", result);
NSString *dataStr = [[NSString alloc] initWithData:fileContents encoding:NSUTF8StringEncoding];
NSLog(@"%@\n", dataStr);
} else {
NSLog(@"%@\n%@\n", routeError, networkError);
}
}] setProgressBlock:^(int64_t bytesDownloaded, int64_t totalBytesDownloaded, int64_t totalBytesExpectedToDownload) {
NSLog(@"%lld\n%lld\n%lld\n", bytesDownloaded, totalBytesDownloaded, totalBytesExpectedToDownload);
}];
- 文件删除
[[client.filesRoutes delete_:@"/test/path/in/Dropbox/account"]
setResponseBlock:^(DBFILESMetadata *result, DBFILESDeleteError *routeError, DBRequestError *networkError) {
if (result) {
NSLog(@"%@\n", result);
} else {
// Error is with the route specifically (status code 409)
if (routeError) {
if ([routeError isPathLookup]) {
// Can safely access this field
DBFILESLookupError *pathLookup = routeError.pathLookup;
NSLog(@"%@\n", pathLookup);
} else if ([routeError isPathWrite]) {
DBFILESWriteError *pathWrite = routeError.pathWrite;
NSLog(@"%@\n", pathWrite);
// This would cause a runtime error
// DBFILESLookupError *pathLookup = routeError.pathLookup;
}
}
NSLog(@"%@\n%@\n", routeError, networkError);
}
}];
- 文件上传
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);
}];
- 解除授权链接
[DBClientsManager unlinkAndResetClients];
@end