SwiftでDropboxを利用するメモ
(注意:ほぼ自分用のメモです)
Dropboxを使う理由
現在自分用の簡単な消費管理アプリを作りたいと考えており,そのデータの保存先を色々検討していました. 次のような選択肢が考えられます.
前者2つはコストがかかるので見送り,UserDefaultに全部しまってしまうのもアプリらしくない(?),Google SpreadsheetにはSwiftのライブラリがない(自分でAPIを叩く必要)などの理由から,今回はDropboxを利用してみることにしました.
SwiftyDropbox
DropboxをSwiftから使うためのライブラリです.
使い方は上のREADMEに書いてある通りになります.
インストールなど
行なった操作は次の通り.
- pod経由でインストール
- Dropboxのサイトでcreate app -> API_KEYの取得
- Info.plist編集その1 LSApplicationQueriesSchemes
- Info.plist編集その2 CFBundleURLTypes
ここでInfo.plistにdb-<APP_KEY>
という形で値を指定するのですが,プロジェクトをGithubなどに公開したときにこれはAPP_KEY
は漏れても大丈夫なのか?と感じました(自分は初心者なのでわからないのですが,多分SECRET_KEY
の方が漏れなければ大丈夫なのかな,と考えてます,公開するときまでには調べなければ)
コーディング
基本的には次の3つを記述すれば動作します.
- AppDelegateの
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
内で
DropboxClientsManager.setupWithAppKey("<APP_KEY>")
これでAPP_KEY
を登録します.
- ボタンを押した時などのメソッド内で
DropboxClientsManager.authorizeFromController(UIApplication.shared, controller: self, openURL: { (url: URL) -> Void in UIApplication.shared.openURL(url) })
するとボタンを押すとログイン画面が出るようになります. ただこれだけだと最後のAllowを押してもブラウザが終了しません.
- AppDelegate内で
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { if let authResult = DropboxClientsManager.handleRedirectURL(url) { switch authResult { case .success: print("Success! User is logged into Dropbox.") case .cancel: print("Authorization flow was manually canceled by user!") case .error(_, let description): print("Error: \(description)") } } return true }
を丸々追記. これで上記のログイン画面でAllowなどを押すと終了し,結果が返ってくるようになります.
- ファイルをアップロードするには,同様にボタンなどを押した時などのメソッド内で
if let client = DropboxClientsManager.authorizedClient { let fileData = "testing data example".data(using: String.Encoding.utf8, allowLossyConversion: false)! let request = client.files.upload(path: "/pocket_management/sample.txt", input: fileData) .response { response, error in if let response = response { print(response) } else if let error = error { print(error) } } .progress { progressData in print(progressData) } } else { // error print("not logged in") }
のようにやるのが良さそうです. clientの取得はControllerで1個用意しておくよりも毎回optional bindingで呼び出した方が良いのか…? (そのほうがエラー処理が書きやすそうに思える)
終わりに
本当にメモですが書いておきました. せっかくアプリを作るのでデザインからやったり色々試してみようと思います.