ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Core DataでAppを作成する
Core Dataは、App全体のデータフローの管理に役立ちます。このセッションでは、派生属性、履歴のトラッキング、変更の通知、バッチ操作など、コードをよりシンプルかつパワフルにするCore Dataの新機能についてについて説明します。また、こうした機能の使用方法と、Appをより効率的に実行するためのUIKitとFoundationの新しい差分出力用APIの詳細を紹介します。
リソース
関連ビデオ
WWDC20
WWDC19
-
ダウンロード
(音楽)
こんにちは (拍手) Core DataでAppを作成する セッションにようこそ Core Dataチームの スコット・ペリーです 今日は素早いリフレッシュのため ベストプラクティスに焦点を当てます Core Dataの起動方法と Appの設定方法について説明します マルチコーディネータの使用方法に ついても説明します 最後は役立つテストの紹介です
では始めます 今年は サンプルAppがリリースされました セッション202で見た方も いるでしょう ポストのリストから始めます
画面上部の+ボタンをタップして ポストを追加します DetailViewControllerを開きます 見た目はブログのAppに似ています タイトル コンテンツ 複数のタグを サポートしています 複数のメディアも対象で 画面下部にサムネイルを表示します
タイトルを変更してから タグを追加してみましょう
どうでしょう
いいですね これは保存して ListViewに戻りましょう
次はTagManagerです 今はポストが3つある Demoというタグが1つあります タグを2つ追加します 1つは“Cats”で― もう1つは“Dogs”です ではこれを閉じて― ツールバーに戻って ランダムにポストを追加します いかがでしょう
タグリストに戻れば確認できます DogsはCatsよりも人気がありますね これぞ科学です (笑い声)
アプリケーションは確認できたので 次はデータの型です
一番分かりやすいポストから 始めます 複数あるサポート対象の メディアタイプとは別です 同じ理由でタグタイプも必要です 添付はとても大きいので 別で保存します リストではサムネイルを表示し データは他の場所に保存します
データの型ができあがりました これはCore Dataモデルに翻訳する 分かりやすいプロセスです Model EditorとXcodeを 使用するためです 次にモデルタイプの種類と リレーションシップを定義します
例えば添付とそのデータは 一対一対応になっています つまり1つの添付は 1つの画像データと結びつき― 1つの画像データは 1つの添付だけを表します
モデル内のCore Dataについては 添付を削除する場合― 画像データも自動的に削除されます これがカスケード削除です
二重の矢印が多過ぎる リレーションシップを示しています 1つのポストに 多くの添付のある場合があります 1つの添付は 1つのポストにしか付きません ポストにタグが たくさん付くことがあります どのタグも多くのポストに 付けられます これは多対多の関係になっています
これで管理オブジェクトモデルを 定義できました App作成前にCore Dataの 種類について さらに説明します PersistentStoreCoordinatorには モデルが必要です 名前で表す通り 永続ストアを管理するためです ファイルシステムのデータベースで 一度に多くのストアができます NSPersistentStoreにある カスタムメイドのタイプもあります
ManagedObjectContextは 頻繁に使われるタイプです Core Dataが使用するコマンドには コンテキストを示す方法があります フェッチ要求を実行する場合 コンテキストが必要です 管理オブジェクトの変更が未保存だと コンテキストがコマンド上に記録します コンテキストの動作のために コーディネータが必要です コーディネータはモデルを理解し ストアの意味を理解します タイプはすべて充分に 相互依存しています カプセル化し全スタックを 表現するタイプが1つあります それが永続コンテナです
永続コンテナを使うと短いコードで スタックを設定できます 特にモデルが バンドルにある場合です
名前で参照さえすれば 永続コンテナがそれをロードします
モデルがコードで生成された場合か 複数のコンテナで同じ物を使う場合 制御用にイニシャライザが もう1つ必要です
一旦コンテナを入手すると 永続ストアをロードできます ロードしたブロックをストア毎に nilエラーで呼び出します その後で管理オブジェクトの コンテキストに目を移します
コンテキストを使用し管理データに シームレスアクセスをします 表示をドライブする場合などに 有用なオプションがあります
まずはクエリの世代管理です ストアデータの表示が安定し オブジェクトへのアクセスが改善します 他の人が変更や 削除をする場合でもです
有効にするにはコンテキストの クエリ世代をcurrentに設定します currentは フローティングメタバージョンです コンテキストのクエリはストアへの 次のアクセスに固定されます
これでコンテキストはストアで 安定してデータを表示できます 次は最新の状態を保持する方法です コンテキスト用に 登録し通知を保存します コンテキストも設定できます 最新の状態を兄弟が 保存した変更として継続できます
自動的に変更が 親から事実になります
スタックの全タイプを設定したので アプリで使う方法を考えましょう ストア要求とインタラクションで コンテキストを使用する場合― コンテキストキューで実行されるべき という点が最も重要です バックグラウンドコンテキストには それぞれのキューがあります
キューを使用して APIの実行を要求します 不変量と非同期バージョンを ブロックします 非同期の動作では実際に コンテナが― コンテキストを作成する バックグラウンドタスクを試みます ブロックが返ると 自動的にそのタスクを並べます
次はアプリケーションにデータを 追加する方法です 2つのオブジェクトだけが 必要な場合― Xcodeで生成された 管理オブジェクトのサブクラスが― 提供するイニシャライザを 容易に使用できます サブクラスを使用するモデルが 1つの場合エンティティは明確です よって コンテキストと共に使用できます コンテキストと共に登録されれば 他のインスタンス変数と同様です contextSaveメソッドを呼び出し ストレージに保存します
もっとデータが必要な場合は? Appの多くは一度に膨大な オブジェクトを処理するには不十分です serverが数百や数千毎に オブジェクトを送信します 2つのオブジェクトの処理と同様 一度に1つの物を保存します ボイラープレートが多いとすぐに インメモリを使い尽します
バッチ挿入の入力は 本日話す最初の新機能です このコードフラグメントは 1000のオブジェクトと同等です 文字列キーのある辞書配列で ペイロードを開始します
このキーはモデルの属性に 名前が載っている必要があります 独特な制約がない場合は そのままにできます デフォルト値を設定すれば Core Dataはその値を使用します
この場合3つの辞書にはコンテンツと タイトル属性がそれぞれあります
元のコードに戻りましょう 挿入要求バッチとオブジェクト モデルエンティティを作成します Xcodeによる管理オブジェクトの メソッドも利用できます
要求を実行します コンテキストがBooleanのラップで 応答を返し結果が分かります
すべて無料です あなたはこう考えるでしょう 売りは何だ? 実際 優位性は多くありません バッチによる更新や削除の経験が あれば理解いただけるでしょう
既存のオブジェクトではなく 独自の制約がある場合― 辞書に合わせるとデータベースの 移動や新しい値に更新できます
オプションまたはデフォルト値の 属性も削除します 独自の制限があるオブジェクトの 更新では既存の値を変更しません
さらにリレーションシップにも 影響が出ます バッチ挿入はリレーションシップの 設定には使用しません 独自制約がありバッチ挿入で 既存のオブジェクトを更新する場合 既存のリレーションシップだけが 残ります
また他のバッチ処理のように バッチ挿入が― contextDidSaveNotificationを 生成しないため自己管理が必要です データができたのでコントローラが 必要であることについて話します
コントローラがやることには データのフェッチと表示があります こちらをご覧ください
フェッチ要求を使用して ストアのオブジェクトを取得します 新しいオブジェクトを作成する時に エンティティを取得したようにします Xcodeで作成した管理オブジェクト サブクラスタイプのメソッドです 事前に設定したフェッチ要求を 使用できます
要求に述語を追加し 結果の精度を上げます ここでは名前でタグを フェッチします
要求を実行すると その結果を 表示の設定に使用します
不変のデータに対して 精度が高いです ビューの使用中にタグの名前や色を 変更する場合はどうでしょう 管理オブジェクトのコンテキストが プロパティの更新を確認します その変更を見る必要性は 確認していません
ご存知のように管理オブジェクトは キー値の監視をサポートしています フレームワークを組み合わせると SwiftでKVOを容易に使えます 各プロパティのオブジェクトの外に パブリッシャーを作って結び付け― ビュー上で データフローを割り当てられた― サブスクライバーに同期します タグの色についてはタイプの一覧を 作成中にマッピング手順を行います
必要なコードはこれで全てです ViewsContentsはオブジェクトを 変更すれば自動的に更新されます (喝采と拍手) 組み合わせが機能し フレームワークをスクラッチしません 強力なデータフロー機能が さらにあります 詳細については セッション721をご参照ください
このコードの展開でごまかしが あったことに気付きましたか DetailViewsはオブジェクトを 表示中にフェッチしません このビューは管理オブジェクトの 親にプッシュされるもので― 実際に書いたコードは こちらになります
ParentからDetailViewへは 一覧になっています CollectionやTableViewなどです フェッチ要求でオブジェクトを 取得できますが― まだ説明していないプロパティが あります 多くのオブジェクトを フェッチする場合に重要な物です
最初はrequestSortDescriptorsです 結果の出力順を定義しています 今回は名前でタグを ソートしています 名前が一意になっていない場合 ディスクリプタを追加し区別します
便利なオプションの1つに バッチ処理もあります フェッチ要求が1400万の オブジェクトに合致する場合― 一度でメモリに ロードしたくはありません あり得ませんが十分にメモリが あるとしても長い時間がかかります 1度にロードするオブジェクト数を フェッチバッチサイズに設定します アプリケーションの反応が 大きく変わります 出力結果とインタラクションが関わる 場合 MS Arrayとして動作します Swiftの配列のブリッジ機能が 最適化を無効にします
この知識を利用すれば 確認したいタグを全てフェッチする―
フェッチ要求の設定は非常に簡単です しかし変更があったら どうしますか
詳細なビューでのオブジェクトの プロパティ使用時に― オブジェクトが経路変更に ついて行く方法が必要です
Core DataはFetch Results Controllerクエリをサポートします タイトル順のポストを一度に50ずつ 全てをフェッチする設定をしました
フェッチ要求はコンテキストで つながれ― これからお話しするfetchedResults Controllerタイプを設定します デリゲートプロトコル経由で 変更をフェッチ要求に伝えます フェッチの実行を確認すると すぐに動作を開始します
Fetch Results Controllerは すでにご存知の方も多いでしょう デリゲートプロトコルが コールバックの報告を変更します 他にセクションが変更される場合の 通知方法があります 更するオブジェクトと変更方法を 通知する別の方法もあります そして これで― メソッドの説明は以上です UITableViewのAPIを並べるよう これらのメソッドは設計されています 適量のグルーコードがテーブル再描画と 経路クエリの結果を一致させます さらに新規CollectionViewでは 変更― コールバックパターンを サポートしません
Fetch Results Controllerには 新しい仕組みが追加されました NSDiffableDataSourceSnapshotの インスタンスの発表が1つ目です (拍手) 皆さんもこのタイプは ご存知でしょう コレクションまたはTableViewの 構造を示す新しいUIKit MapKitです TableViewデータソースを DiffableDataSourceとして設定し スナップショットを取り使用します これらのタイプはセッション220で 説明していますが― 必要なのはCollectionViewを 1行のコードで最新に保てることです そのコードはスライドの 表示に合っています かつては多くの ボイラープレートでした ここではDiffableDataSourceに スナップショットを提供するだけです スナップショットと 以前のビューを比較すると DiffableDataSourceになります コンピュータの違いを使用して ビューを更新します (拍手) ついに実現しました (笑い声) DiffableDataSourceの スナップショットは CollectionViewの 制御に役立ちます よりカスタマイズできる物を 探すか― またはTableとCollection以外の タイプを管理するとします そんな時 興味深い 別のデリゲートメソッドがあります このメソッドでも1つのFetched Resultsに全変更をまとめます ただし別のタイプを使用し今年は CollectionDifferenceになりました 名前の示す通り― CollectionDifferenceが2つの コレクション差をエンコードします
Swift標準ライブラリの差は Swift Evolutionのドキュメントで 紹介しました しかしそれはFoundationにもあり セッション711で説明します
これは一次元タイプで セクションフェッチを使用しない 場合だけサポートされています SnapshotDelegateメソッドのように レポートメソッドの変更を除きます Fetched Resultsコントローラで 複数の物をドライブする場合― 複数のFetched Results コントローラを使用します
CollectionViewの1セクションを ドライブする方法を見てみましょう これらの差を使用します
デリゲートメソッドです まずはバッチの更新から開始します そして差分の変化をループします
CollectionDifferencesは 挿入と削除をサポートします 反対のタイプの2つの変更が 相互に参照する場合があります 最初の部分は削除に 関連する挿入です これはオブジェクトの 移動か変更です 実際には論理的な位置には 移動していません CollectionViewはこの差分を 説明できるため問題ではありません 適切な送信先の IndexPathsがある限り― 適切に動作します 2つ目はFetched Resultsではない オブジェクトの挿入です CollectionViewに追加を指示します
最後は移動に関係のない削除です 新しい関連性をフィルタ処理し CollectionViewから削除します
ここまでです コードの構成が良くなったと 分かります 機能を考慮することで ボイラープレートが減る良い例です 必要な物は― CollectionViewと差分だけです この新しいデリゲートメソッドは 皆さんが気に入ると思います しかし今年は 旧来の物も一新されました Swift UIフレームワークが宣言的 インターフェイスをサポートします ただしスナップショットや差分は 利用できません このモデルタイプはFetched Resultsの リストから得られます さらに既存のコントローラである didChangeContentDelegateMethodが― Fetched Resultsの設定の更新毎に ビューが更新されます
Fetched Resultsのビューへの 適用が容易になりました 出力結果自身がフェッチを 難しくしている場合はどうでしょう フェッチ要求を 作成できない場合は? フェッチ要求を実行する時に― またはパフォーマンスの問題が ある場合は? 明らかな点はコントローラの ニーズがモデルのニーズを超え― 目的を達成するためにモデルの 純度を諦める必要があります 今回は非正規化でこれを実行します
WWDC 2018のセッション224でも 非正規化について少々話しました 要約すると非正規化ではデータの コピーで効果的にアクセスできます 代償として余分なデータを維持する オーバーヘッドがあります でもこの代償を相殺する場面は たくさんあります データベースのインデックスが 良い例です インデックス化された列のコピーを 全て維持する代わりに― これらのデータに依存している場合 軽くて速いクエリが得られます
元のアプリケーションを 考えてみます 非正規化は各タグを使用している ポスト数の記録にも便利な道具です
必要なのは整数属性を― postCountというタグタイプに 追加するだけです
次に必要なのはポストのタグ付けや 削除ごとに増減する― 新しいpostCount属性の 確認だけです これで このコードにバグはなく データは永久に矛盾しませんよね? (笑い声) ですよね? (笑い声) 違いますね 派生属性の話をしましょう (笑い声) 派生属性はCore Dataで維持される 正規化されたメタデータです ただ数を数えているのでは ありません ドキュメンテーションにあるように 多くの機能がサポートされています
派生属性は管理オブジェクトの モデルで定義されています XcodeのModel Editorが 新しいインターフェイスを持ちます 新しいタイプを使用してコードに 派生属性を定義することもできます それが NSDerivedAttributeDescriptionです
また派生表現がエンティティの プロパティを参照できます 1段階深くなります
派生属性は非正規化を容易にします 適用方法の説明に 少々お時間をいただきます
先程と同じ アプリケーションがあります Tag Managerを見ると― タグが3つと 多くのポストがあります これをドライブする ビューコードは― リレーションシップポストを 通して数を数えます 実行すると リレーションシップで失敗します より大きなデータが多くあれば パフォーマンスの問題で終了します モデルの派生属性を使用して 修正しましょう
モデルエディタです タグタイプを見て下さい こちらに移動します
postCountという新しい属性を 追加します 整数タイプを選択します
こちらのインスペクタを捜すと― “Derived”の 新しいチェックボックスがあります これをクリックすると “Derivation”が表示されます 基本的にはコードを ビューからこちらへ移動します “posts. @counts”と入力します 属性機能を使用します
これで終わりです リビルド時は管理オブジェクトの サブクラスをXcodeがリビルドします ビューに戻って確認します
これがpostCountという 新しいインスタンス変数です オプションではないので 条件を 削除してコードを軽くできます ビルドして起動すると― 何も変わらないことが分かります (笑い声) 早くなっただけです 良くもなっています 全てを最新に保つ必要はありません 案の定― この通りです (拍手) サポート対象の属性のセットは デベロッパDocにあります 大体4つのクラスに 分けられています 添付IDや画像データのコピーなどの 完全な重複が一番簡単です 他の派生にはフィールドの 簡単な変換もあります 小文字のタグ名や標準化された ユニコード文字列などです
リレーションシップ全体を通して 集計関数の例をデモの中で見ました 最後にグローバル関数を見ましょう パラメータが全くないので オブジェクトが更新された時に― 記録を取る場合などは便利です コントローラの設定は以上です 高度な項目とScalingを説明します PersistentHistoryは 2017年に発表されました インポータを使用して追加する データ処理のツールです また同じストアを使用する 複数のコーディネータの間で― データの正確性を維持します
今年は新しいフェッチ要求を 採用しました 必要な履歴だけを 検索しやすくなりました
Extensionによる変更を 検索することがあるでしょう またはポストに 影響を与える変更だけや― 一定時間内の履歴だけを 検索することもあります Persistent Historyに与える フェッチ要求の力は何でしょう
NSPersistentHistoryTransactionと NSPersistentHistoryChangeは― モデルタイプではありません しかし新しいクロスメソッドを 発生させ― フェッチ要求と機能させています 見ていれば― Xcodeで作成した管理オブジェクト用 メソッドに似ていると分かります
サブクラスタイプのエンティティの 説明用アクセサリなどがあります インスタンスを返す設定をされた フェッチ要求の作成方法もあります NSPersistentHistoryTransactionか NSPersistentHistoryChangeかを― 実行時に返します フェッチ要求をプレディケートに設定し 管理オブジェクトをフェッチします コンテキストにフェッチ要求を 直接実行する代わりに― PersistentHistoryRequest の一部をフェッチ要求は使用します
NSPersistentHistory ChangeRequest に新しいイニシャライザがあります フェッチ要求の 新しいインスタンスと― 設定後に使用できる不変の プロパティを作成します
PersistentHistoryのフェッチ要求を 結び付けAppの精度を上げます いつ履歴が作成されたかを知る方法に 疑問がわくでしょう
実行する方法はいろいろありますが 全て欠点があります 変更毎にストアを プルすることができます 変更が通知される前に無駄な努力と 遅延の間の適切な妥協点を見つけ― 解決策を調整することは難しいです Dispatch SourcesやFSEventsなどの ファイルシステム監視システムは― バックストアだけで 動作するため採用はできません ストアの変更に未対応の通知を 大量に受信する可能性があります これは多くの無駄な努力になります
便利なバンドエイドがある一方― 他人がストアを変更した時が 分からない問題が残ります
今年新しい通知を発表します 相互コーディネータが 通知を減らします しかしイベントは 同時には発生しません 相互コーディネータが 通知を変えます Remote Change Notificationsです
Remote Change Notificationsを 有効にすると― 新しいPersistentStore オプションが表示されます NSPersistentStoreRemoteChange NotificationPostOptionKeyです
ストアディスクリプションに設定後 コーディネータにロードします するとコーディネータが Remote Changeを待機します このオプションは変更があれば Remote Change Notificationsを 送信させます 通知を変更する場合 使用するのは全コーディネータの― NSPersistentStoreRemoteChange NotificationPostOptionKeyです 対象は変更だけではありません PersistentHistoryも 有効にしたいでしょう Remote Change Notificationsが 通知のユーザ情報の辞書にある― NSPersistentStore URLキーで ストアの変更を通知します PersistentHistoryを有効にすると これも履歴トークンになります 今お話ししたPersistentHistoryの フェッチ機能と一緒に使用します Remote Change Notificationsは プッシュ通知のような物だからです 一度に多くの変更があると 最後のみ実行されるかもしれません アプリケーションを 起動する場合― 現在のPersistentHistory Tokenを どうやって知るのでしょうか 永続ストアコーディネータの 新しいメソッドで分かります
CurrentPersistent HistoryTokenです 以前は解けなかったパズルを 解くために新しいツールがあります タイミングに合った方法で 状態を保つだけでなく― PersistentHistoryを減らし 作業に影響のある変更だけになります
これを理解するのに最適な 別のデモがあります 同じアプリケーションで 見てみましょう
これはコントローラです コーディネータが変更する毎に ビューコンテキストを最新にします storeRemoteChangeという メソッドがすでに登録してあります Remote Change Notificationを 受信する度に呼び出します
ここでプルするのは― ユーザ情報辞書以外にある 新しいPersistentHistory Tokenです 更新するコンテキストをグラブし ブロックを実行します
必要なPersistentHistoryを 削減するために最初に― 最新の履歴トークンに基づいて 述語をビルドします アプリケーション起動だけの場合 現在のPersistentHistory Tokenです 全トランザクションを入手します その後または同時に 通知の履歴トークンを入手します
トランザクションの作者を 使用する必要がある場合 トランザクションを 確認できる述語も作成します 別のコーディネータが 作成したトランザクションです
履歴のフェッチ要求を作成して トランザクションを入手できます 合成された述語と 先ほど作成した別の述語で設定されます 別のコーディネータに作成された トランザクションのみ入手できます 最後に確認した物と新しい物と 包括的に作成した物です
NSPersistentHistory ChangeRequestを 作成しフェッチ要求を設定します コンテキストに対して 再度実行します
最新ではないトランザクションの リストが表示されます objectIDNotificationの ユーザ情報辞書をそれぞれ― 引き出せます 渡し先は― ManagedObjectContextMethod mergeChanges fromRemoteContextSave これは2017年に発表しました
トランザクションが処理されると ビューが最新データに更新されます ローカルなプッシュ通知は速いので ほぼリアルタイムで終了します
それから次回不要な作業はしません 最新のPersistentHistory Tokenだけ 覚えてください 新規のRemote Change Notificationを 再開できます
ここまで― PersistentHistoryのフェッチとRemote Change Notificationの説明でした (拍手) 最後に― テストの話のために お時間をください
皆さんは複数の設定やDesanitizersを 使用し各リリースをテストしますね Core Dataについて もう少々 アドバイスしたいと思います
まずパフォーマンスの目標を 理解すること 1万個以上のオブジェクトを使用して 目的達成には線形アルゴリズムを デスクトップで使用することもできます 写真アプリケーションの場合は 全てのオブジェクトが対象になり logarithmic timeより遅い場合 アプリケーションはハングします 軽やかにテストするためには 重要なことです パフォーマンスのデータセットで 統合テストを実施します
しかし他の問題を検出するには最適な 運用中の設定が必要です Core DataのAppではフレームワーク 内蔵の同時デバッグを使用できます これを有効にします Scheme Editorに移動し プロセス引数リストに― com.apple.CoreData ConcurrencyDebugged1を設定します
複数の設定で統合テストをすると 長時間かかります 同様にユニットテストを できるだけ早く終わらせたい テストの実行時間が重要な場合は インメモリのストアを使用します この場合は特にインメモリモードの SqLightStoresのことです
SqLightStoreではインメモリモードが サポートされています 永続コンテナの作成と ストアのロードの間に― ストアディスクリプションを取得し URLプロパティ設定にdev/nullを書くと
良いパフォーマンススタックの完成です このインメモリストアは コーディネータ間で共有できません 実行したRemote Change Notificationを有効化するには 名前を付けたインメモリストアを 利用します dev/nullの後にパスの コンポーネントを追加し定義します URLのある他のSqLightStoreから インメモリデータベースに接続します
異なるコーディネータが インメモリストアを共有し― Remote Change Notificationsも 互いにディスパッチします これで全てのロジックを テストできます
最後にSanitizersを使用します 少なくとも1度は助かったと 思うでしょう 信頼できるSanitizerで1Byteの オーバーフローをすぐ発見しました 個別試験では 数か月かかったでしょう 同様にスレッドSanitizerが 重大なセクションを把握して インハウスで再現できない スレッドのレースを知らせます 最後にUBSanについてです 変更が起きた時に起こりうる未定義の 動作を特定し バグを未然に修正します Core Dataを使用する設定方法を 確認しました 新旧のAPIを使用した― モデルとコントローラの間の小型で シームレスで堅牢な統合の設定です 複数のコーディネータ間で 同期し続ける方法を試してみました ニーズを明らかにしテストを行ったので 自信を持って出荷できます
いつも通りご意見を伺います Feedback Assistantをご利用ください 詳細については デベロッパWebサイトをご確認ください 今日のセッションのページには話に出た 別セッションへのリンクも含みます では明日のラボで ありがとうございました (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。