[xcode] Dropbox SDK 使用 IOS

DropBox SDK 分成了三類型

  1. Datastore API (文字類型)
  2. Sync API (文字&圖檔)
  3. Core API (任何資料)

依照使用的資料形態,選擇要用哪個API。

1.Datastore - 類似資料庫的形式。

2.Sync - 文字&圖檔都儲存在Dropbox上,可以上傳並且下載,多裝置存取同一資訊

比較方便。

3.Core API - 變化性較大,複雜性高的資料存取,可以自己撰寫自己的上傳下載方式。





Sync API

下載&教學都在此,https://www.dropbox.com/developers/sync


先在網站上建立app資訊。





選取你要建立的是哪種。

選取要儲存的資料是哪種。

App key,App secret 這兩個資訊要填入自己的軟體裡。


回到Xcode開發界面加入以下的framework,到專案中。

CFNetwork.framework
Security.framework
SystemConfiguration.framework
QuartzCore.framework
libc++.dylib

Targets-專案-info-URL types

在URL type中加入一個新的URL
URL Schemes 鍵入db-APP_KEY

下載回來的dropbox.framework 也要拉進專案中
程式段。

AppDelegate.m

記得import
#import Dropbox/Dropbox.h

剛剛在網站取得的兩個資訊,在這邊填入。
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {
    DBAccountManager *accountManager =
        [[DBAccountManager alloc] initWithAppKey:@"APP_KEY" secret:@"APP_SECRET"];
    [DBAccountManager setSharedManager:accountManager];

    return YES;
}
在填入以下
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
sourceApplication:(NSString *)source annotation:(id)annotation {
    DBAccount *account = [[DBAccountManager sharedManager] handleOpenURL:url];
    if (account) {
        NSLog(@"App linked successfully!");
        return YES;
    }
    return NO;
}

呼叫登入頁面

同樣的記得import Dropbox/Dropbox.h到自己的class裡面


- (IBAction)didPressLink {
    [[DBAccountManager sharedManager] linkFromController:YOUR_ROOT_CONTROLLER];
}

到此步驟就可以叫出登入頁面。


取消連接


[[[DBFilesystem sharedFilesystem]account]unlink];



接著要先判斷是否有登入過,在檔案上傳跟下載的時候才能正常使用。

DBAccount *account = [[DBAccountManager sharedManager] linkedAccount];

if (account) {
    DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account];
    [DBFilesystem setSharedFilesystem:filesystem];
}
可以簡單的作為判斷是否有登入過


- (void)viewWillAppear:(BOOL)animated {

    DBAccount *myaccount = [[DBAccountManager sharedManager]linkedAccount];
    if(myaccount){
        DBFilesystem *filesystem = [[DBFilesystem alloc]initWithAccount:myaccount];
        [DBFilesystem setSharedFilesystem:filesystem];
        NSLog(@"link");
    }
    else{
        NSLog(@"not link");
    }
}


檔案上傳

DBPath *newPath = [[DBPath root] childPath:@"hello.txt"];
DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
[file writeString:@"Hello World!" error:nil];
讀取檔案,必須要已經存在Dropbox上

DBPath *existingPath = [[DBPath root] childPath:@"hello.txt"];
DBFile *file = [[DBFilesystem sharedFilesystem] openFile:existingPath error:nil];
NSString *contents = [file readString:nil];
NSLog(@"%@", contents);
取得Dropbox 上的檔案清單


DBPath *path = [DBPath root];
    NSArray *fileInfos = [[DBFilesystem sharedFilesystem]listFolder:path error:nil];
    for (DBFileInfo *info in fileInfos) {
        NSString *name = info.path.name;
        NSLog(@"%@",name);
    }


刪除檔案


DBPath *path = [[DBPath root]childPath:@"hello.txt"];
[[DBFilesystem sharedFilesystem]deletePath:path error:nil];



以上是一些基本的操作方式,Dropbox也提供Sync這部分的範例,在下載回來的檔案中。

Sync範例部分並沒有在手機內儲存檔案,而且要取得上傳跟下載的進度有點麻煩,

檔案類型較為複雜的時候,也很難使用。還不如直接使用Core API 來得方便。




Core API

下載&教學在此https://www.dropbox.com/developers/core/sdks/ios

在Core API中下載回來的是,DropboxSDK.framework跟Sync API使用的並不一樣

不能通用。

一開始同要在要Dropbox網站上先申請好(大致跟上面的申請法一樣,不重複啦)


回到Xcode開發界面加入以下的framework,到專案中。

CFNetwork.framework
Security.framework
SystemConfiguration.framework
QuartzCore.framework
libc++.dylib

Targets-專案-info-URL types

在URL type中加入一個新的URL
URL Schemes 鍵入db-APP_KEY

下載回來的DropboxSDK.framework 也要拉進專案中

程式段

AppDelegate.h

#import <DropboxSDK/DropboxSDK.h>


AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    DBSession* dbSession =[[DBSession alloc]initWithAppKey:APP_KEY appSecret:APP_SECRET root:kDBRootAppFolder];
    [DBSession setSharedSession:dbSession];
    return YES;
}


- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    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;
}


自己的Class.h

一樣要import DropboxSDK/DropboxSDK.h


在interface中要加入 DBRestClientDelegate

@property (readonly , nonatomic)DBRestClient *restclient;



自己的Class.m

開頭加入下行


@synthesize restclient = _restclient;


連接Dropbox,可以寫在按鈕事件當中

if (![[DBSession sharedSession] isLinked]) {
        [[DBSession sharedSession] linkFromController:yourRootController];
    }

取消連接Dropbox,同樣也是按鈕事件。


if ([[DBSession sharedSession] isLinked]) {
        [[DBSession sharedSession] unlinkAll];
    }

restclient的delegate


-(DBRestClient*)restclient{
    if(!_restclient){
        _restclient = [[DBRestClient alloc]initWithSession:[DBSession sharedSession]];
        _restclient.delegate = self;
    }
    return _restclient;
}


上傳檔案,一開始要先取得手機端的檔案路徑,接著指定Dropbox存放路徑,

接著就是寫入檔案,這邊跟Sync寫入有所不同的地方是,Dropbox上如果有相同檔名,

上傳以後並不會覆蓋原先的檔案,Dropbox會額外更名為test(1).png。

NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *locals = [path objectAtIndex:0];
NSString *localPath = [NSString stringWithFormat:@"%@/test.png",locals];//手機端,上傳檔案的路徑
//NSLog(@"%@",localPath);
NSString *destDir = @"/";//Dropbox存放的路徑
[[self restclient] uploadFile:@"test.png" toPath:destDir withParentRev:Nil fromPath:localPath];


上傳成功事件

- (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);
}


進度條,可以把上傳的進度丟到ProgressView元件

-(void)restClient:(DBRestClient *)client uploadProgress:(CGFloat)progress forFile:(NSString *)destPath from:(NSString *)srcPath{
    progressview.progress = progress;
}



讀取Dropbox 檔案清單,記得先做取得清單,不要在執行事件的時候才做,會有延遲而導致

清單還沒抓好,裡面是空的。


[[self restclient]loadMetadata:@"/"];

這邊用了dropboxlist 來放檔案清單

- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
    dropboxlist =[[NSMutableArray alloc]init];
    if (metadata.isDirectory) {
        NSLog(@"Folder '%@' contains:", metadata.path);
        for (DBMetadata *file in metadata.contents) {
            NSLog(@"%@",file.filename);
            [dropboxlist addObject:file.filename];
        }
    }
}

- (void)restClient:(DBRestClient *)client loadMetadataFailedWithError:(NSError *)error {
    
    NSLog(@"Error loading metadata: %@", error);
}


下載

[[self restClient] loadFile:dropboxPath intoPath:localPath]


下載完成


- (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);
}

沒有留言:

張貼留言