01
Dec
雲端備份小貓萌照的 Dropbox API
Facebook

雲端的資料備份,一直是App 開發者很想帶給使用者,卻又害怕碰觸的危險功能。雲端備份帶給使用者安全感,保證App 資料永久保存,但對開發者而言,它卻像是危險的不定時炸彈。它需要龐大的金錢以負擔與日俱增的機器和流量需求,而且若是開發的程式有缺陷,還可能遺失使用者寶貴的資料。如今隨著雲端備份的第一把交椅Dropbox 大方地提供API,備份功能成為一件既安全又不花一毛錢即可提供的App 功能。接下來就讓我們從頭打造一個備份可愛小貓妹妹圖片到Dropbox 空間的App 吧,有了Dropbox 的雲端備份,再也不用擔心遺失妹妹每一張珍貴的超萌照片。

撰文:彼得潘

 

建立Dropbox App 

想要在iOS App 裡提供備份到Dropbox 的功能,首先我們必須先在Dropbox 的開發網站上建立對應的Dropbox App。

1. 連線到Dropbox 開發網站並登入

https://www.dropbox.com/developers 

2. 點選左邊側邊欄的App Console 進入App 的管理頁面

若是第一次建立Dropbox App,必須先同意相關的開發條款。勾選I agree 選項,點選Submit 後,將跳出Email 認證視窗。點選SendEmail 按鈕,再到信箱收信認證。認證後再度回到App Console 頁面,點選Create App 按鈕,即可自由地建立Dropbox App。

3. 設定Dropbox App 相關資訊

(1) 選擇Dropbox API app 

有2 種Dropbox App 可建立,Drop-ins app 和Dropbox API app。在此我們目標使用Dropbox 最火紅的檔案存取功能,希望可以將App 資料備份到Dropbox,並且希望了解Dropbox API 的設計精髓, 因此請選擇Dropbox API app。

 

(2) 選擇Files and datastores 

我們希望可以上傳小貓可愛的圖檔,因此選擇包含檔案的Files and datastores。

 

(3) 選擇Yes,限制只能存取App資料夾裡的檔案 

我們希望到時候小貓可愛的圖案可以擁有自己的獨立空間,儲存於專屬的資料夾。因此我們選擇YES, 如此使用者的Dropbox 空間裡將新增一個對應到此Dropbox App 的資料夾來儲存App 的備份檔案。如果選擇No 了話,App 將可以存取使用者在Dropbox 上的任何檔案。

 

(4) 設定App 名稱為Cute Cat 

到時候使用者Dropbox 空間裡的資料夾也將命名為Cute Cat。

 

4. 記住App 的App key 和App secret 

在Cute Cat 的settings 頁面,除了待會開發iOS App 需要用到的App key 和App secret 之外,還有以下2 個欄位也值得瞧個幾眼。

 

(1) Status: 

預設是Development, 未來我們開發的iOS App 上架時, 切記要將Dropbox App 的status 改為production,如此才能讓任何人的Dropbox 帳號都能使用App 裡的Dropbox 功能。

 

(2) Development users: 

在development 模式, 預設只有開發者自己的Dropbox 帳號可以存取剛剛建立的Dropbox App Cute Cat。如果想讓其它人測試,必須點選Enable additional users,才可享有100 個Dropbox 帳號測試的額度。

 

下載 Dropbox Core API SDK 

為了在iOS App 裡提供檔案備份至Dropbox 的功能,我們需要使用Dropbox Core API SDK,因此請先下載相關的SDK。於Dropbox 開發網站上,點選左邊側邊欄的Core API,從下載頁面清單裡找到iOS,點選它的Install SDK。

 

點選Download iOS SDK 下載Dropbox Core API SDK。

 

將Core API SDK 加入專案

從剛剛解壓縮下載的資料夾dropbox-ios-sdk-1.3.9 裡, 點選DropboxSDK.framework,將它加到專案裡。 

 

設定DBSession 物件

為了使用Dropbox 的強大功能,我們需要DBSession 物件的幫忙。有了DBSession 物件,Dropbox 帳號登入和檔案上傳下載的相關功能,都彷彿變成了如舉手之勞般的輕鬆小事! 

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWit hOptions:(NSDictionary *)launchOptions 

{

// Override point for customization after application launch. 

DBSession* dbSession = 

[[DBSession alloc] 

initWithAppKey:@"9wqq7x2t1" 

appSecret:@"6xnwnaji" 

root:kDBRootAppFolder]; 

[DBSession setSharedSession:dbSession]; 

return YES; 

 

在App 啟動時,建立DBSession 物件。DBSession 物件的初始化method 如下: 

- (id)initWithAppKey:(NSString *)key appSecret:(NSString *)secret root:(NSString *)root; 

參數說明: 

key: 傳入App key 

secret: 傳入App secret 

root: 傳入kDBRootAppFolder,表示到時候只會存取Dropbox App 資料夾,而不是使用者Dropbox 上的所有檔案。

 

Dropbox 帳號登入

在App 存取使用者的Dropbox 空間前,使用者必須先登入自己的Dropbox 帳號。接著就讓我們實作Dropbox帳號登入的功能。

 

1. 設定Dropbox 登入狀態開關

在App 的畫面上添加表示登入狀態的UISwitch 開關物件, 將view controller 的property dropboxSwitch 連結到它,並設定此開關的valuechanged event 連結到controller 的dropboxSwitchValueChange: method。

 

2. 設定Dropbox 登入開關的on / o 狀態

 

- (void)viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

if([[DBSession sharedSession] isLinked])

{

self.dropboxSwitch.on = YES;

}

else

{

self.dropboxSwitch.on = NO;

}

}

 

利用DBSession 物件的isLinked method 判斷前是否登入Dropbox,

若是已登入開關將顯示on 的狀態,否則將為off。

 

3. 定義Dropbox 登入開關狀態改變觸發的dropboxSwitchValueChange: method

 

- (IBAction)dropboxSwitchValueChange:(UISwitch*)sender { 

if(sender.isOn) 

{

[[DBSession sharedSession] linkFromController:self]; 

}

else 

{

[[DBSession sharedSession] unlinkAll]; 

 

如果開關從o 切換到on,表示使用者想要登入,呼叫DBSession物件的linkFromController: method 開始Dropbox 登入流程。若是使用者安裝了Dropbox App,此時將切換至Dropbox App,否則將顯示Dropbox 的登入網頁。

 

4. 登入結果回報

 

- ( B O O L ) a p p l i c a t i o n : ( U I A p p l i c a t i o n * ) a p p l i c a t i o n handleOpenURL:(NSURL *)url { 

if ([[DBSession sharedSession] handleOpenURL:url]) { 

if ([[DBSession sharedSession] isLinked]) { 

// At this point you can start making API calls 

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@" 連線建立成功" message:nil delegate:nil cancelButtonTitle:@"Ok" 

otherButtonTitles:nil]; 

[alertView show]; 

}

else 

{

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@" 連線建立失敗" message:nil delegate:nil cancelButtonTitle:@"Ok 

otherButtonTitles:nil]; 

[alertView show]; 

}

return YES; 

}

// Add whatever other url handling code your app requires here 

return NO; 

 

當登入流程完成後,將再度切換回iOS App,此時AppDelegate 的application:handleOpenURL: method 將被呼叫。在此method 裡我們可以利用DBSession 物件的isLinked method 判斷是否登入成功。

 

5. 設定登入流程完成後,重新啟動App 需要的URL Scheme 欄位 

當完成Dropbox 的登入流程後,需要透過App 的URL Scheme 來切換回原本的App。換句話說,我們需要設定App 的URL Scheme,以便到時候Dropbox App 或是網頁利用此scheme 啟動我們的App。

(1) 切換到App 的Info 頁面, 點選最下方URL Types 區塊的+ 按鈕

(2) 設定URL Schemes 欄位,輸入 db- 加 app key。比方 當app key 為123456 時,此處即輸入db-123456。

 

執行App 

點選開關,完成Dropbox 的登入。

 

上傳檔案

現在終於可以開始做正事了。前面一連串的努力,都是為了將珍貴的小貓妹妹超萌圖片傳到Dropbox 上。為了怕突然天崩地裂,來不及備份圖片,讓我們趕緊來完成這最後一哩路吧。

1. 準備小貓妹妹的可愛圖片cat.jpg 

2. 在App 畫面上添加上傳圖片的button, 並設定button 點選時觸發method uploadFile: 

3. 定義上傳小貓萌照的uploadFile: method 

 

- (IBAction)uploadFile:(id)sender { 

if([[DBSession sharedSession] isLinked]) 

{

if(restClient == nil) 

{

restClient =[[DBRestClient alloc] initWithSession:[DBSession sharedSession]]; 

restClient.delegate = self; 

}

NSString *imageName = @"cat.jpg"; 

N S S t r i n g * l o c a l P a t h = [ [ N S B u n d l e m a i n B u n d l e ] pathForResource:imageName ofType:nil]; 

NSString *destDir = @"/"; 

[restClient uploadFile:imageName toPath:destDir 

withParentRev:nil fromPath:localPath]; 

}

 

 

當牽扯到檔案的上傳下載時,我們需要透過DBRestClient 物件。因此我們利用DBSession 物件建立DBRestClient 物件,然後再將controller 設為它的delegate,如此才能取得檔案上傳下載的進度和結果回報。

呼叫DBRestClient 物件的uploadFile:toPath:withParentRev:fromPath: method 上傳檔案,此method 的宣告如下: 

- (void)uploadFile:(NSString *)filename toPath:(NSString *)path withParentRev:(NSString *)parentRev 

fromPath:(NSString *)sourcePath; 

參數說明: 

lename: 到時候儲存在dropbox 上的檔案名稱

path: 上傳檔案儲存的路徑,在此我們傳入/,表示儲存於Dropbox App Cute Cat 資料夾下。

parentRev: 檔案的版本,在此我們傳入nil,表示此為全新的檔案, 不會覆蓋已存在的檔案。

sourcePath: 欲上傳檔案在手機上的路徑,在此我們傳入cat.jpg 於 手機上的路徑。

 

4. 定義DBRestClientDelegate 關於上傳檔案的相關method,取得上傳結果。(於ViewController.m 裡加入) 

 

- (void)restClient:(DBRestClient*)client uploadedFile:(NSString*)destPath 

from:(NSString*)srcPath metadata:(DBMetadata*)metadata { 

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedSt ring(@"create back up success", nil) message:nil delegate:nil 

cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 

[alertView show]; 

}

 

當檔案順利傳至Dropbox 上時,此method 將被呼叫。

 

- (void)restClient:(DBRestClient*)client uploadFileFailedWithError:(NSErr or*)error { 

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedSt ring(@"create back up fail", nil) message:nil delegate:nil 

cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 

[alertView show]; 

}

 

當檔案不幸地上傳失敗時,此method 將被呼叫。

 

當小貓妹妹可愛的照片順利上傳到Dropbox 後,我們即可於Dropbox 的App -> Cute Cat 下找到牠的芳蹤 ! 

 

關於彼得潘

如果我會作詞作曲, 

我就能成為創作歌手。

我有一絲音感嗎?沒有。

所以,很可惜,我只能當歌手的朋友。

如果給我一天一個App 的負荷, 

也澆不熄我對蘋果的熱情。

一天能夠完成一個App 嗎?可以。

所以,是的,我是愛瘋一切為蘋果的彼得潘。

著有App 程式設計入門 (博客來電腦類Top 1) 

facebook:http://www.facebook.com/iphone.peterpan