iOSでdropbox連携を行う(第3回)

iOSのdropbox連携の第3回。
前回でやっとdropboxのログイン認証までできましたので、
今回からは実際にデータを取得していきます。
実は前回までの内容は公式のマニュアルを見れば全て乗っているので、
そのままの手順を踏めば問題なく実行できるものでした。(多少の補足などは行いましたが)
私もここまでは何の問題もなくすんなりといきました。
ですが、ここから先が少し手探りとなります。

1.ファイルリストの取得

まずは、dropbox内のファイルリストを取得したいと思います。
先述の公式マニュアルを見ると、Specify API call response queueの項目にそれっぽいのがあります。

let client = DropboxClientsManager.authorizedClient!

client.files.listFolder(path: "").response(queue: DispatchQueue(label: "MyCustomSerialQueue")) { response, error in
    if let result = response {
        print(Thread.current)  // Output: {number = 4, name = (null)}
        print(Thread.main)     // Output: {number = 1, name = (null)}
        print(result)
    }
}

説明分を読むと
『デフォルトではリクエスト/レスポンスはメインスレッドで実行されるので、
別スレッドで実行するには上のようなresponseメソッドを使って実行スレッドを設定します。』
という感じの事が書かれています。
つまりは、このコードを実行すると、メインスレッドとは別のスレッドで処理が行われるという事みたいですね。
そして、実行内容としては files.listFolder(path:””) とあるので、おそらくこれでTopフォルダのファイルリストが得られるのでしょう…
試しに、ViewControllerの viewDidLoad で記述してみましょう。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let client = DropboxClientsManager.authorizedClient
        
        client?.files.listFolder(path: "").response(queue: DispatchQueue(label: "MyCustomSerialQueue")) { response, error in
            if let result = response {
                print(Thread.current)  // Output: {number = 4, name = (null)}
                print(Thread.main)     // Output: {number = 1, name = (null)}
                print(result)
            }
        }
    }
    ……
}

これで実行すると…
あれ?何も起きない…ログに何も表示されない……
多分、dropboxの認証が行われていないのでエラーになったのでしょう。
前回作成した認証ボタンを使って一度ログイン認証を行ってからもう一度アプリを立ち上げてみます。

{number = 4, name = (null)}
{number = 1, name = (null)}
{
    cursor = “****************”;
    entries =     (
                {
            ".tag" = folder;
            id = "id:bLMfqIGYb7MAAAAAAAABGg";
            name = "\U30d7\U30ed\U30b8\U30a7\U30af\U30c8";
            "path_display" = "/\U30d7\U30ed\U30b8\U30a7\U30af\U30c8";
            "path_lower" = "/\U30d7\U30ed\U30b8\U30a7\U30af\U30c8";
            "shared_folder_id" = 105655634;
            "sharing_info" =             {
                "no_access" = 0;
                "read_only" = 0;
                "shared_folder_id" = 105655634;
                "traverse_only" = 0;
            };
        },
……
                {
            ".tag" = file;
            "client_modified" = "2012-02-29T10:31:46Z";
            id = "id:bLMfqIGYb7MAAAAAAAABHQ";
            name = "\U306f\U3058\U3081\U306b.pdf";
            "path_display" = "/\U306f\U3058\U3081\U306b.pdf";
            "path_lower" = "/\U306f\U3058\U3081\U306b.pdf";
            rev = 70647110c;
            "server_modified" = "2012-02-29T10:31:46Z";
            size = 231991;
        },
……
    );
    "has_more" = 0;
}

今度は何か取れました。
先ほどのは、やっぱり認証ができていなくてエラーになってたみたいですね。
レスポンス内容を見ると、“.tag”のfolderとかfileとかでフォルダ/ファイルが判別できるみたいですね。
そして、”name”にフォルダやファイル名が入っているようです。
Unicodeエンコードされているので分かりにくいですが、ちゃんとファイル名が取れています。
試しにコードをこのサイトでデコードしてみたら、ちゃんと日本語のファイル名が取れます。

2.データの取り出し

1.にてTop階層のフォルダとファイルが取得できているのを確認できました。
ですが、result変数にデータが入っているのはわかりますが、どうやって取り出すのでしょう?
公式のドキュメントを見ても分かりやすく記載されていなかったので色々を探ったところ、

                for elem in result.entries {
                    print(elem.name)
                }

でファイル名のリストが取れました。

プロジェクト
Photos
Public
private_data
カメラアップロード
program
共有テスト
勉強会資料
はじめに.pdf
ゲーム作りのフロー_120302.ppt
SDキャララフ.lip
test120509.java
memo.txt
MP_プロット
画面仕様書考案メモ

ですが、これではそれがフォルダなのかファイル名なのか判断がつきません。
他のメンバも確認して見ましたが、どれを使ってもダメでした。
どうやら、この取り方では情報が欠落してしまうようです。
1.の結果を見る限りではresultの中に”.tag”という情報は入っているのに…

とりあえず、今回の目的である、フォルダ名・ファイル名は取得できました。
ですが、今回の結果では、フォルダならさらにその中を見に行くなどの対応が取れません。
さらにはファイルの更新日時やサイズなども取れません。
(正確には取れているけど、オブジェクトから取り出せません)

実は、SwiftyJSONというJSONライブラリを使っての解析など色々試して見たのですが、どうもうまくいきませんでした。
(公式マニュアルで記載しているのとは別のメソッドを使った時はうまく取れたのですけど…)
今回はここでタイムアップしてしまいましたので、
次はもう少しこのあたりを掘り下げていこうと思います。
(補足回として第3.5回で掘り下げました)

Posted in システム開発 and tagged .