プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

SwiftのOneDrive APIでディレクトリを作成する。

この記事は2018年07月01日に投稿しました。
この記事は2018年08月04日に更新しました。

目次

  1. はじめに
  2. ディレクトリ作成処理
  3. おわりに

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。

OneDrive APIディレクトリを作成してみます。
ファイルの作成同様、ディレクトリ作成のAPIが見つからなかったので、OneDriveのREST APIを使ってディレクトリを作成します。

目次へ

2. ディレクトリ作成処理

手順としてはファイルの作成と同じになります。
違う点としては次に4点になります。

  1. URL文字列が異なる。
  2. HTTPリクエストヘッダのContentTypeが異なる。
  3. HTTPパラメータの設定が必要
  4. HTTPメソッドが異なる。

ファイルの作成とディレクトリの作成で、"1. URL文字列"が異なるのは当然だと思います。
しかしディレクトリの作成の場合、"3. HTTPパラメータの設定"が必要となり、それに合わせて"2. HTTPリクエストヘッダのContentType"と"4. HTTPメソッド"も変更になります。

import OneDriveSDK

/**
 ディレクトリを作成します。

 - Parameter parentId: 親ディレクトリのID
 - Parameter dirName: ディレクトリ名
 */
func createDir(_ parentId: String, dirName: 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/\(parentId)/children"
    // 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")

    // HTTPパラメータを生成し、設定します。
    let emptyParams = Dictionary<String, String>()
    let params = ["name": dirName,
                  "folder": emptyParams,
                  "@name.conflictBehavior": "rename"] as [String : Any]
    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: params, 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 200, 201:
            // 正常終了の場合、正常時に行う処理を記述してください。
            break

        default:
            // 上記以外のHTTPステータスコードはエラーとして、処理を終了します。
            // 必要に応じてエラー処理を行ってください。
            break
        }
    })
    // HTTP通信タスクを実行します。
    task.resume()
}

目次へ

3. おわりに

今思えばファイル作成のメソッドと手順は同じなので、うまく差異を切り出せば処理を共通化できると思います。
しかし当時は、うまく動作しなくて試行錯誤しながら実装したので、ファイル作成のメソッドとは分けることにしました。
特にHTTPパラメータの設定方法がわからず苦労しました。
機会があればリファクタリングしたいところです。

転職を本気で考えている方向けのプログラミングスクール!【WebCampPRO】

目次へ