iPhoneアプリとDropBoxを連携する
最近iOSアプリを作っています。
エディタ系のアプリなのでファイルを、iPhone⇔iPad間で同期できればいいな、、、 と思ってると
DropboxのAPIが結構いい感じ! ファイルをDropbox上に保存しておいて、端末間でファイル同期ができます。
なのでDropbox連携を組み込むことにしてみました。
その記録をメモっておきます。
前にQiitaに書いたもののまとめです...
[1]Dropboxのデベロッパ登録
登録
まず作るアプリごとにDropboxに登録する必要があります。
下記 URL の”Create app”よりアプリを登録します。
https://www.dropbox.com/developers/apps
まずは各種設定です。
はじめにDrop-insとDropbox API
今回は一番柔軟に実装ができるCore APIを使いたいので、DropBox APIを選びます。What type of data...
ファイルを丸ごと保存したいのでFile and DataStoreを選びます。 DataStoreとはDropboxが提供するkey-value型のストレージのようです。Can your app limited ...
Yesを選びます。 自分のアプリで保存したファイル以外は操作しないのでYesを選びます。 自動的に自分のアプリ用のフォルダが各ユーザのDropbox内に作られて、そこがルートフォルダになります。アプリ名
適当に入れます。他のアプリと重複しなければOKです。
確認
登録完了です。 APP Key、App Secretは後で使う事になります。
[2]SDK組み込み
XcodeにSDKを組み込んで、認証させるところまでやります。
SDKダウンロード
Xcodeに組み込み
解凍したファイルをXcodeのプロジェクトツリーにドラッグ&ドロップします。
Security.framework とQuartzCore.frameworkの設定
- Security.framework
- QuartzCore.framework
を設定する必要があります。
xcodeのファイルエクスプローラーでターゲットのプロジェクトを選択し、
"Build Phases"タブの"Link Binary with Libraries"の"+"ボタンをクリックします。
表示されたダイアログでSecurity.frameworkを検索して追加します。
QuartzCore.frameworkについても同様に繰り返します。
URL Schemaの設定
xcodeのファイルエクスプローラーでターゲットのプロジェクトを選択し、 "info"→"URL Types"の"URL Schemas"に db-APP_KEY (APP_KEYは先ほど取得したもの)と入れる
[3]認証処理のコーディング
Dropboxアカウントの認証はOAuthで行いますが、ややこしいOAuth認証は全てライブラリがやってくれます。
以下に手順をまとめます。
まずは初期化の処理です。
下記のAPP KEY, APP SECRETには、先ほどデベロッパーサイトで入手したものを指定してください。
* AppDelegate.m
#import <DropboxSDK/DropboxSDK.h> DBSession *dbSession = [[DBSession alloc] initWithAppKey:@"INSERT_APP_KEY" //デベロッパーサイトで入手したもの appSecret:@"INSERT_APP_SECRET" //デベロッパーサイトで入手したもの root: kDBRootAppFolder]; // kDBRootAppFolder or kDBRootDropbox ※アプリ毎のフォルダを作ってる場合kDBRootAppFolder [DBSession setSharedSession:dbSession];
次に
適当なボタンを押した時に、以下メソッドを実行します。
初回はDropboxのパスワード入力用の画面が表示されます。
* ViewController.m
- (IBAction)didPressLink {
if (![[DBSession sharedSession] isLinked]) {
[[DBSession sharedSession] linkFromController:self];
}
}
最後に認証完了の処理を追加します。
* AppDelegate.m
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url sourceApplication:(NSString *)source annotation:(id)annotation { if ([[DBSession sharedSession] handleOpenURL:url]) { if ([[DBSession sharedSession] isLinked]) { NSLog(@"App linked successfully!"); // At this point you can start making API calls } return YES; } // Add whatever other url handling code your app requires here return NO; }
[4]エミュレータで確認
ビルドして先ほどのボタンを押して認証処理を走らせます。
Dropboxのパスワードを入力する画面がニョキニョキっと出てこればOKです!
[5]ファイルのアップロード,ダウンロードなどなど
DBRestClientを作る
DropBoxと連携するテキスト編集アプリをつくってるとします。まずDBRestClientを準備します。DBRestClientは様々なファイル操作の入口になります。
- YourViewController.m
#import <DropboxSDK/DropboxSDK.h>
@interface YourViewController () <DBRestClientDelegate>
@property (nonatomic, strong) DBRestClient *restClient;
@end
...
- (void)viewDidLoad {
[super viewDidLoad];
self.restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
self.restClient.delegate = self;
}
ファイルのアップロード
DBRestClientの準備ができたら、まずはファイルのアップロードを試してみます。
[DBRestClient uploadFile:toPath:withParentRev:fromPath:]
でアプリ内のローカルファイルをDropBoxにアップロードできます。
以下はworking-draft.txtというファイルを作ってDropBoxにアップロードするサンプルコードです。 新規ファイルの場合は上書き保存を防ぐために、prentRevをnilにしておきます。 既存ファイルを上書きする場合には、parentRevに現在のrevを指定します。これはmetadataのrev属性から取得できます。
- YourViewController.m
// Write a file to the local documents directory NSString *text = @"Hello world."; NSString *filename = @"working-draft.txt"; NSString *localDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *localPath = [localDir stringByAppendingPathComponent:filename]; [text writeToFile:localPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; // Upload file to Dropbox NSString *destDir = @"/"; [self.restClient uploadFile:filename toPath:destDir withParentRev:nil fromPath:localPath];
全てのDBRestClientのメソッドは即座に戻り値を返さず、代わりに結果を返すDBRestClientDelegateを2つ(成功/失敗)持っています。 uploadFileのcallbackは以下の2つになります。
YourViewController.m
- (void)restClient:(DBRestClient *)client uploadedFile:(NSString *)destPath from:(NSString *)srcPath metadata:(DBMetadata *)metadata { NSLog(@"File uploaded successfully to path: %@", metadata.path); } - (void)restClient:(DBRestClient *)client uploadFileFailedWithError:(NSError *)error { NSLog(@"File upload failed with error: %@", error); }
上記のUploadFileを実行して、成功すればコンソールログに以下のようなログが出るはずです。
File uploaded successfully to path: /working-draft.txt
DropBox上のファイル一覧取得
次にDropBox上のファイル一覧を取得します。
loadMetadta
を実行します。
YourViewController.m
[self.restClient loadMetadata:@"/"];
結果は以下のコールバックで取得できます。
ViewController.m
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata { if (metadata.isDirectory) { NSLog(@"Folder '%@' contains:", metadata.path); for (DBMetadata *file in metadata.contents) { NSLog(@" %@", file.filename); } } } - (void)restClient:(DBRestClient *)client loadMetadataFailedWithError:(NSError *)error { NSLog(@"Error loading metadata: %@", error); }
メタデータには現在のrevisionが格納されています。revisionはあらゆるファイル変更がなされたときに更新されます。revisionをローカルファイルにも保存しておけば、revisionを比較して更新すべきかどうか判断できます。
DropBoxからファイルをダウンロード
次にDropBox上のファイルをダウンロードしてみます。
ダウンロードには[DBRestClient loadFile:intoPath:]
を使います。
適当なViewControllerで以下を実行します。 dropboxPathはDropBox内のファイルパスです。上記のDBMetadataのpath属性で取得できます。 localPathは端末内の保存したい場所のファイル名フルパスです。
- YourViewController.m
[self.restClient loadFile:dropboxPath intoPath:localPath];
ダウンロード完了時に呼ばれるコールバックは以下になります。
YourViewController.m
- (void)restClient:(DBRestClient *)client loadedFile:(NSString *)localPath contentType:(NSString *)contentType metadata:(DBMetadata *)metadata { NSLog(@"File loaded into path: %@", localPath); } - (void)restClient:(DBRestClient *)client loadFileFailedWithError:(NSError *)error { NSLog(@"There was an error loading the file: %@", error); }
DropBoxのファイルを削除
ファイル削除には[DBRestClient deletePath:dropboxPath:]
を使います。
YourViewController.m
[self.restClient deletePath:dropboxPath];