検索プロバイダーは、fetchItems 関数を使用して、アイテムの検索と結果のフィルタリングを行います。fetchItems 関数は、以下のようなシグネチャを持っています。
// context: the necessary search context (for example, tokenized search and
// sub-filters).
// items: list of items to populate (if not using the asynchronous api)
// provider: the Search Provider itself
public delegate IEnumerable<SearchItem> GetItemsHandler(SearchContext context,
List<SearchItem> items,
SearchProvider provider);
SearchProvider は、新しい SearchItem を items リストに追加するか、IEnumerable<SearchItem> を返さなければなりません。
注意非同期
fetchItemsAPI を使用しない場合、fetchItems関数でnullを返さなければなりません。
SearchItem は単純な構造体です。
public struct SearchItem
{
public readonly string id;
// The item score affects how Search sorts the item within the results from the Search Provider.
public int score;
// Optional: Display name of the item. If the item does not have one,
// SearchProvider.fetchLabel is called).
public string label;
// If the item does not have a description SearchProvider.fetchDescription
// is called when Search first displays the item.
public string description;
// If true, the description already has rich text formatting.
public SearchItemDescriptionFormat descriptionFormat;
// If the item does not have a thumbnail, SearchProvider.fetchThumbnail
// is called when Search first displays the item.
public Texture2D thumbnail;
// Search Provider user-customizable content
public object data;
}
SearchItem では id だけが必須です。
ヒント:
SearchContext.searchTextに従ってフィルタリングする場合、静的関数SearchProvider.MatchSearchGroupで部分検索を行うことができます。
アイテムに対してファジーサーチを使うには、以下の例のように FuzzySearch.FuzzyMatch を使用します。
if (FuzzySearch.FuzzyMatch(sq, CleanString(item.label), ref score, matches))
item.label = RichTextFormatter.FormatSuggestionTitle(item.label, matches);
すべての検索アイテムは、同じプロバイダーのアイテムに対して score でソートされます。スコアが低いアイテムがリストの一番上に表示されます (昇順ソート)。
非同期 fetchItems API は、検索プロバイダーの結果計算に時間がかかる場合や、WebRequests などの非同期検索エンジンに依存する場合に使用できます。
非同期 API を使用するには、fetchItems 関数が IEnumerable<SearchItem> を返すようにします。IEnumerable<SearchItem> は、結果を返す関数である必要があります。API が一度に 1 つのアイテムをフェッチできるからです。
IEnumerable<SearchItem> が返されると、アプリケーションの更新の間に enumerator (列挙子) が保存され、繰り返し実行されます。列挙型は、終了するまで、複数のアプリケーションの更新にわたって継続されます。
UI がブロックされないように反復処理時間は制限されます。ただし、この呼び出しはメインスレッドで行われるため、結果が準備できない場合は、できるだけ早く yield する必要があります。
以下の例は、非同期の fetchItems API を使用する方法を示しています。
public class AsyncSearchProvider : SearchProvider
{
public AsyncSearchProvider(string id, string displayName = null)
: base(id, displayName)
{
fetchItems = (context, items, provider) => FetchItems(context, provider);
}
private IEnumerable<SearchItem> FetchItems(SearchContext context, SearchProvider provider)
{
while(ResultsNotReady())
{
yield return null;
}
var oneItem = // Get an item
yield return oneItem;
var anotherItem = // Get another item
yield return anotherItem;
if(SomeConditionThatBreaksTheSearch())
{
// Search must be terminated
yield break;
}
// You can iterate over an enumerable. The enumeration
// continues where it left.
foreach(var item in someItems)
{
yield return item;
}
}
}
AssetStoreProvider.cs: WebRequest を使って Asset Store にクエリを行います。ESS.cs: Entrian Source 検索インデックスを起動するプロセスを作成し、プロジェクト内のアセットに対する完全なテキスト検索を提供します。