ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
macOSにおけるFileProviderを使用したファイルのクラウドへの同期
FileProviderフレームワークを使用して、包括的なクラウド同期ソリューションを構築する方法を紹介します。ファイルプロバイダExtensionの構築方法を示し、そのExtensionをファイルシステム機能(セーフ保存、ディスクスペース管理、Finder統合など)に簡単に統合する方法を検証します。
リソース
関連ビデオ
Tech Talks
-
ダウンロード
♪ ♪ こんにちは Cloud File ProvidersチームのJohannesです macOSにおけるファイルプロ バイダについて紹介します ユーザーファイルをmacOS に同期させるクラウド ストレージベンダーにとって最適な回です 紹介の後 ファイルの同期に関するユーザー フローについて説明します 次にXcodeでのフローを1つ実行し 各フローのサポートの 順序について説明します 追加オプションの 統合ポイントの概略を説明し次のステップに 移ります まずファイルプロバイダの機能を説明しましょう
クラウドストレージをmacOSのファイル システムに統合することができます 新規APFS機能によりユーザー ファイルとフォルダを オンデマンドダウンロードすることが出来ます APIは完全にユーザースペースにあります macOSでのカーネル拡張機能 は推奨されていないので syscallのインターセプトや オンデマンドでの ファイルダウンロードを FUSEまたはKAUTHに 依存している場合はこれが適切な代替手段です
アップロードやダウンロードをし リモートの変更事項を伝えるだけでいいのです システムがローカルでの変更事項を通知し 残りを全て処理します これらの機能は全てFinderを始めとする システムに確実に統合されています プロバイダがサイドバーに表示されます ファイルステータスは Finderに表示・追跡されます UIとのカスタマイズ可能な統合ポイントは 複数あります システムと統合するための App拡張を実施します ライフサイクルはユーザーの操作により異なります 最初にユーザーがクラウドストレージからアクセス 可能なファイルツリーを示すドメインを作成します システムはそのドメインを Finderのサイドバーに 公開しファイルシステムにドメインの ルートディレクトリを作成します この時点ではデバイスにデータはありませんが ユーザーとルートはやりとりが可能です どうしてでしょうか? ルートはデータレスディレクトリと呼ばれています APFSの新規オブジェクト であり それを認識して やりとりするためのAPIもあります 更にデータレスオブジェクト が非準備な状態で起こる プロセスに対して透過的であることは重要な点です 読み取りにより ダウンロードが作動し読み取り再開の許可前に ファイルのデータレスプロパティが失われます このプレゼンではファイルプロバイダの フレームワークがデータレスファイルの 読み取り時にコールバック される仕組みを説明します それでは同期と実行のユーザーフローを 見てみましょう 同期ダウンと同期アップの主要なフローを 4つ見てみましょう どのフローでも新規データが必要になると システムが拡張機能を呼び出します
クラウドサーバーと通信してデータを引き出し 完了ハンドラを呼び出して 応答できることをお見せします まずデータレスファイルが読み取られた時に何が 起こるかを見てみましょう
カーネルがデータレスファイルへの読み取り アクセスを検出すると 内容をフェッチするために 拡張機能が呼び出され その間システムコールは一時停止します 拡張機能のfetchContents法 が呼び出されます 通常はダウンロード時に実行します 完了後にcompletionHandler が呼び出されます ファイルは先のデータレスファイルを 埋めるシステムに渡されオープンファイル ディスクリプタは無効化されません システムは読み取りアクセス の一時停止を解除します これでファイルはデータレスではないので 以降の読み取りに拡張機能を使う必要はありません ディレクトリの列挙がこれとよく似ています カーネルがreaddirの呼び出 しを検出し一時停止します 拡張機能を呼び出してディレクトリ内の アイテムを列挙します このアイテムのメタデータを サーバーからフェッチします そしてアイテム数を返信します 列挙はページ付けされます フルセットアイテム数より 少ない数を返すことが出来 システムは中断した場所から 列挙を取得します 全ページの列挙が済むとシステムは 元の呼び出しを許可します ファイルの場合と同様に 一度ディレクトリが 列挙されると以降のreaddir の呼び出しにはディスクの コンテンツが利用されるため 拡張機能を用いる必要はありません
ただリモートでコンテンツが 変更されるとどうでしょう? リモートでの変更はシステム に通知する必要があります その方法を見てみましょう リモートで変更があると サーバからMacへのプッシュ 通知の送信が可能になります そのプッシュ通知に応答して 特別な列挙子の .workingSetから 列挙の必要のある変更が あることをシステムに通知します システムは方向転換し.workingSetで 変更されたアイテムを列挙します syncAnchorという継続トークンを 新規変更点の列挙に利用します このトークンは拡張機能によって定義されます システムは最後に列挙された syncAnchorを追跡します enumerateChanges法を syncAnchorから列挙子を呼び出します これに対して変更アイテムを返し 完了後に次回使用する 新しいsyncAnchorを提示して下さい システムは非同期で作動し ユーザーに表示されるファイルを更新します APFSのコンペア・アンド・ スワップ機能を利用して ローカルでの変更がプロセス中に 失われないようにします さらにシステムはファイル調整とアドバイザリ ロックメカニズムを a統合してAppとの 調整を図ります
この3つのメカニズムにより クラウドでファイルを同期し リモートでの変更時も同期を維持することが 可能となります 最後にローカルの変更をクラウドに同期します ローカルの変更をシステムが検出し 拡張機能でmodifyItem法を呼び出し 変更フィールドのセットを正確に渡します 低レベルのイベントを集約することにより同期に 意義のあるイベントとします 例えばカーネルが安全な保存物を検出しアイテム 識別子を新規ファイルIDに 透過的に再マップします 一致するパッケージレベルの 変更を要求して提示すると システムはパッケージファイルも圧縮します
modifyItemの呼び出しに 応じて サーバ側の アイテムの状態を更新します ファイルの内容が変更された 場合 システムは変更後の クローンを提示するので更に変更された場合にも 一致するバージョンでアップロード可能です
完了後completionHandlerを 呼び出します completeHandlerは アイテムのバージョン 識別子を更新し拡張機能への変更の 送信確認に使用されます またcompletionHandlerは アイテムの最終状態をパラ メータとして受け取ります クラウド内のアイテムの更新 内容がリモートの変更内容と 競合する場合 その状態が 変更される可能性があります 最終状態を戻すとシステムはアイテムの ローカルの状態を更新してクラウドの正しい内容と 一致させることができます
5つ目は明け渡しです 急ぎでディスク容量が必要な場合 システムは ファイルプロバイダー拡張子を含めずに ローカル ファイルを自動的に削除します これはユーザーがビデオ録画 をしている時やソフトウェア アップデートをダウンロード している時に発生する可能性があります 新規ファイルの書き込みに必要なディスク領域を 確保するためにシステムは最低の使用頻度の ファイルの最小セットを削除します この推移を見てみましょう ローカルファイルがデータレスファイルに変換され データレスファイルがロー カルファイルに変換されます リモート作成のファイルはデータレスで開始でき ローカル作成のファイルは データレス開始できません ただし全ファイルを削除出来る訳ではありません システムはアップロード済と報告した ファイルのみを削除して 再度ダウンロードできるようにします 従ってアップロードされたファイルとされていない ファイルの2種類があります ローカルでの編集後は新バー ジョンのファイルをアップロ ードする必要があるため 削除できない状態に戻ります
ここ迄は アクセス時のファ イルダウンロードとローカル 編集後のファイルアップ ロードのためにシステムがどのようにファイル プロバイダ拡張機能を呼び出すかを見てきました ディスクプレッシャー による削除には関与していませんが 拡張機能からの削除を 誘発又は防止する方法があります
これには多くの説があります 実際のフローを1つ見てみましょう
小さなローカルファイルサーバを実行するAppを 作成し そのAppにはサーバに逆らって動作する ファイルプロバイダー拡張機能を埋め込みました FruitBasketと言います 既にそのサーバにログイン しているのでサイドバーに ルートフォルダのエントリがあります そのフォルダ内のアイテムに 対してデータレスエントリの 作成の理由となるルートフォルダを選択しました ファイル名の横のクラウド ダウンロードアイコンから データレスアイテムであることが分かります
コマンドラインで”cat”を利用してファイルを 読み取ります データレスファイルのため 拡張機能でコンテンツフェッチされます 既にXcodeの拡張機能に 接続しておりこのコンテンツ フェッチを遮断するブレーク ポイントも設定しています
Catが実行されてブレーク ポイントにヒットしました コンテンツフェッチの完了をブロックしているため ターミナルウィンドウでの 読み取りもブロックされています Finderウィンドウでクラウド アイコンが進捗インジケータ に置き換えられています 一貫性のあるダウンロード ステータスビューが見れます ダウンロード状況が混雑している訳ではなく デバッガでブロックされているため進行状況は 更新されません
続けましょう completeHandlerを呼び出す 直前に2つ目のブレークポイントを設定しました
この時点でプロバイダはファイルの内容を ディスク上のローカルURLに ダウンロードしています completeHandlerを 呼び出すと システムは ユーザーに表示するファイルの内容を ダウンロードしたものと交換します Xcodeを続行してシステムの ブロックを解除しましょう Finderステータスが更新され ローカルファイルであること catプロセスでのブロックの成功が確認できます
ブレークポイントは設定されたままですがローカル ファイルなのでポイントに 到達することなくcatを再度 実行することができます この読み取りは通常のローカ ルファイルに対して行われ 拡張機能は関与しません
勿論これはサンプル ファイルプロバイダのほんの一部の機能です 私達はAPIの全機能を説明し このセッションの一部として ソースコードを公開しています これまで説明してきたフローをどのように 実施するかについてお話しましょう まずシステムに同期の準備が 完了しいることを通知します するとFinderのサイドバーに エントリが表示されます このエントリはドメインと呼ばれ 通常はクラウド サーバのログインセッションに相当します 各ドメインには個別の識別子があり これを表示するには新規インスタンスを作成し マネージャオブジェクトを介して追加します ドメインの削除も可能です 通常これはユーザーのログアウト時に 行われますが 開発初期とテスト時にも有用です ドメインがFinderに表示された状態で エントリに移動すると直ぐに システムは アイテム列挙を要求します ではこれを実施しましょう 最初のステップとしてアイテムクラスを実施します インスタンスは列挙する個々のエントリを 表します 次にシステムからの要求時にアイテムと共に システムを呼び出す列挙を実施します ここでサイドバーのエントリに移動して ディレクトリを確認することができます 勿論このディレクトリ内のファイルは全て データレスです コンテンツフェッチをして これを変更しましょう データレスファイルを開く際にシステムから fetchContents法を呼び出します ファイルをディスク上に ダウンロードしそのURLから completionHandlerを 呼び出します データレスファイルをコンテンツで満たしてから クリーンアップします ディレクトリ構造の同期が維持されるように 別の列挙を実施します リモートの変更を同期します 最初にcurrentSyncAnchor法 を呼び出して 同期アンカーを取得します データベースの変更カーソルを示す データオブジェクトを返します 何らかの変更を通知する度にシステムは 最後に指定した アンカー以降の変更を要求してきます 変更を返し 最後に新たなアンカーを返します 最後のステップは変更の同期の許可です システムがローカルファイルの変更を検出すると 3つの方法からどれかを呼び出して 既存のアイテムを作成 変更又は削除します create法を簡潔に見てみましょう システムから作成のための 新規アイテムを渡されます これはシステムアイテムですが 独自のアイテムと同じプロトコルに従います システムからアイテムに関連する 一連のフィールドも渡されます 例えばアイテムには拡張属性が 付与されている場合とされていない場合があり それを示すフィールドがあります コンテンツフィールドがあればコンテンツを含む ファイルURLを渡してきます フォルダやシンボリックリンクを示すアイテムには コンテンツがありません 新規ローカルアイテムデータ をサーバーにアップロードし 結果のリモートアイテムで completionHandlerを 呼び出します
以上です この時点でmacOSに機能的な ファイルプロバイダがあり オンデマンドでファイルを提供し ローカルの変更をクラウドに リモートの 変更をMacに伝達出来ます ファイルプロバイダフレームワークには 多くの追加のオプション APIがありシステムとの 詳細な統合を可能にします 見てみましょう
アイコン装飾により Finderでアイテムを視覚的に 装飾することが出来ます アイコンにバッジを付け フォルダをエンボス加工し 共有を示すことも出来ます Appで宣言されたUTTypeを介して 装飾用のカスタムアートワークも提示出来ます
コンテキストメニューアクションを使用すると ファイルに対してカスタム アクションが実行可能です UIと非UIのバリエーションがあります 拡張機能のInfo.plistで宣言 されたNSPredicatesにより このアクションを適用する ファイルを定義もできます
プリフライトアラートの使用 により 意図せぬ結果を もたらす可能性のあるアク ションの実行前に ユーザに 警告することが出来ます アラートUIとアラートをアクティブ化する基準は Info.plistでも設定されています
次に貴方は何をしますか? まずセッションのサンプルコードをダウンロード することが出来ます とても包括的で 多くの指針が含まれています 新規拡張機能のターゲットを 既存のAppに追加します 始める際に有用なXcodeの テンプレートがあります そこから説明した順序で メソッドスタブを実施するだけで すぐに稼働することができます このセッションをご覧頂きありがとうございます ファイルプロバイダの 拡張子がmacOSに表示される のを楽しみにしています
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。