この記事は2018年07月04日に投稿しました。
この記事は2018年07月21日に更新しました。
目次
現場のためのSwift4 Swift4.1+Xcode9.3対応
- 作者: 澤田孝志,今村哲也,染谷昌利
- 出版社/メーカー: 秀和システム
- 発売日: 2018/05/23
- メディア: 単行本
- この商品を含むブログを見る
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回はOneDrive APIでファイルコピーをしてみます。
PWEditorでは、ドキュメント"Items in the OneDrive SDK for iOS"の"Copy an Item"を参考に実装しました。
ただしコピー用のAPIが用意されているので簡単と思いきや、罠がありました。
2. ファイルコピー処理
OneDrive APIでコピー行うには、copyメソッドを使用します。
このメソッドで、ディレクトリもファイルもコピーできます。
ディレクトリをコピーする場合、配下のディレクトリやファイルもコピーされます。
コピー先に同名のディレクトリやファイルが存在する場合、エラーになります。
ただし、copyメソッドはコピー先がサブディレクトリの場合のみ使用できるようです。
実装した時は、コピー先がrootディレクトリの場合、うまく動作しませんでした(今はどうかわかりませんが)
そのためPWEditorではコピー先がrootディレクトリの場合、REST APIを使って別メソッドで実装してあります。
サブディレクトリへのコピーはこちらのメソッドを使用します。
import OneDriveSDK /** サブディレクトリにコピーします。 このメソッドでは、"root"ディレクトリへのコピーはできません。 - Parameter parentId: コピー先のディレクトリのID - Parameter fileId: コピー元のディレクトリまたはファイルのID - Parameter fileName: コピー元のディレクトリまたはファイルの名前 */ func copyFile(_ parentId: String, fileId: String, fileName: String) { // 認証済みクライアントオブジェクトを取得します。 guard let client = ODClient.loadCurrent() else { // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。 // 念のためのチェックです。 // 必要に応じてエラー処理を行ってください。 return } // アイテムオブジェクトを取得します。 guard let drive = client.drive(), let items = drive.items(fileId) else { // アイテムオブジェクトが取得できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // ODDItemReferenceオブジェクトにコピー先のディレクトリのIDを設定します。 let parent = ODItemReference() parent.id = parentId // リクエストオブジェクトを取得します。 let request = items.copy(withName: fileName, parentReference: parent).request() // コピーを実行します。 let _ = request?.execute { (item: ODItem?, status: ODAsyncOperationStatus?, error: Error?) -> Void in if let error = error { // エラーの場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // 正常終了の場合の処理を記述してください。 } }
"root"ディレクトリへのコピーはこちらのメソッドを使用します。
import OneDriveSDK /** rootディレクトリにコピーします。 - Parameter fileId: コピー元のディレクトリまたはファイルのID */ func copyFileToRoot(_ fileId: String) { guard let client = ODClient.loadCurrent() else { // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。 // 念のためのチェックです。 // 必要に応じてエラー処理を行ってください。 return } // ベースURLを取得します。 guard let baseURL = client.baseURL else { // ベースURLが取得できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // アカウントセッションを取得します。 guard let accountSession = client.authProvider.accountSession?() else { // アカウントセッションが取得できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // アクセストークンを取得します。 guard let accessToken = accountSession.accessToken else { // アクセストークンが取得できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // URL文字列を生成します。 let urlString = "\(baseURL)/drive/items/\(fileId)/action.copy" // URLを生成します。 guard let url = URL(string: urlString) else { // URLが生成できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // HTTPリクエストを生成します。 let request = NSMutableURLRequest(url: url) // キャッシュをオフにします。 request.cachePolicy = .reloadIgnoringLocalCacheData // HTTPメソッドを設定します。 // 今回は"POST"を使用します。 request.httpMethod = ”POST" // Content-Typeを設定します。 // HTTPパラメータを設定するため、"Content-Type"に"application/json"を設定します。 request.setValue("application/json", forHTTPHeaderField: "Content-Type") // Authorizationを設定します。 // ここでアクセストークンを設定します。 let bearer = String(format: "Bearer %@", accessToken) request.setValue(bearer, forHTTPHeaderField: "Authorization") // Preferを設定します。 request.setValue("respond-async", forHTTPHeaderField: "Prefer") // HTTPパラメータを生成し、設定します。 let params = ["path": "/drive/root"] let parentReference = ["parentReference": params] do { request.httpBody = try JSONSerialization.data(withJSONObject: parentReference, options: JSONSerialization.WritingOptions()) } catch { // HTTPパラメータの設定でエラーの場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // HTTP通信タスクを生成します。 let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in if let error = error { // エラーの場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } // HTTPステータスコードを取得します。 guard let httpURLResponse = response as? HTTPURLResponse else { // HTTPステータスコードが取得できない場合、処理を終了します。 // 必要に応じてエラー処理を行ってください。 return } let statusCode = httpURLResponse.statusCode // HTTPステータスコード別に処理を振り分けます。 switch statusCode { case 202: // 正常終了の場合、正常時に行う処理を記述してください。 break default: // 上記以外のHTTPステータスコードはエラーとして、処理を終了します。 // 必要に応じてエラー処理を行ってください。 break } }) // HTTP通信タスクを実行します。 task.resume() }
3. おわりに
copyメソッドも用意されているし、このメソッドでディレクトリもファイルもコピーできるので、簡単に実装できると思っていましたが、はまりました。
実装した後テストしてみると、"root"ディレクトリへのコピーがどうしてもうまく動作しませんでした。
copyメソッドでいろいろ試しましたがどうしても解決しないため、またもやREST APIを使って自分で実装するはめになりました。
OneDrive APIは用意されているAPIは割と使いやすいようになっていますが、全機能がそろっていないのが玉に傷です。
とりあえず稼ぎたいなら、ITエンジニア【IT派遣テクノウェイブ】
[改訂新版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)
- 作者: 石川洋資,西山勇世
- 出版社/メーカー: 技術評論社
- 発売日: 2018/01/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688