老的Dropbox SDK從去年就廢棄不能用了,公司的App一直沒有修改,所以相關功能一直不能使用,最近恰好交由我完成該功能,在此記錄一下Dropbox API v2集成過程。

1.創(chuàng)建賬號:
- 進入官網:https://www.dropbox.com
- 注冊Dropbox賬號,然后創(chuàng)建app,按照下圖選擇即可:

- 創(chuàng)建好后,就可以獲得
App key和App secret了
屏幕快照 2018-04-13 下午4.11.20.png
注:
可以看到,剛創(chuàng)建的App的status是Development,點擊Apply for production后會進入review流程,review通過后,會變?yōu)?code>Production狀態(tài)。
但是:
此時提交review后Dropbox官方并不會立刻審核,Development狀態(tài)下可以最多供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+系統(tǒng)上運行,如果你的app要兼容iOS9.0以下系統(tǒng),請做好兼容處理,我遇到的兼容問題及解決方法見:http://m.itdecent.cn/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.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>dbapi-8-emm</string>
<string>dbapi-2</string>
</array>
3.主要API說明
- 初始化
DBUserClient:
#import <ObjectiveDropboxOfficial/ObjectiveDropboxOfficial.h> //頭文件
[DBClientsManager setupWithAppKey:@"<APP_KEY>"];
- 授權認證:
[DBClientsManager authorizeFromController:[UIApplication sharedApplication]
controller:controller
openURL:^(NSURL *url) {
[[UIApplication sharedApplication] openURL:url];
}];
授權成功回調:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)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
- 創(chuàng)建文件夾
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);
}
}];
- 獲取文件列表(列表文件多的話支持分段獲?。?/li>
[[client.filesRoutes listFolder:@"/test/path/in/Dropbox/account"]
setResponseBlock:^(DBFILESListFolderResult *response, DBFILESListFolderError *routeError, DBRequestError *networkError) {
if (response) {
NSArray<DBFILESMetadata *> *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<DBFILESMetadata *> *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
