【CoreData】検索フィールドによるデータのフィルタ方法

この記事は約3分で読めます。

CoreDataのエンティティを検索フィールドを使用してフィルタする方法を紹介します。
検索フィールドは、serchableモディファイアを使用するため、iOS 15.0以上の環境で動作します。

前提条件

今回紹介しているコードは、検索部分のみです。
データの追加処理などは別途実装済であることが前提です。

コード例

iOS15.0以上
XCode(当サイトの環境)13.4.1
import SwiftUI
import CoreData

struct SerchSample: View {
    // CoreDataのStaffエンティティをプロパティとして準備する
    @FetchRequest(
        entity: Staff.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Staff.name, ascending: true)],
        animation: .default
    ) private var fetchedStaff: FetchedResults<Staff>
    
    // 検索テキストを格納するプロパティ
    @State var text = ""
    
    var body: some View {
        NavigationView {
            // Staffエンティティの情報をリスト表示する
            List{
                ForEach(fetchedStaff) { staff in
                    Text(staff.name ?? "")
                }
            }
        }
        // 検索フィールドを表示する
        .searchable(text: $text, placement: .navigationBarDrawer(displayMode: .always), prompt: "検索するテキスト")
        // 検索フィールドの値が変更されるごとに"serchResults"を呼び出す
        .onChange(of: text) { newValue in
            searchResults(text: newValue)
        }
    }
    
    // 検索フィールドに入力された値により
    // 取得したStaffにフィルタをかける
    private func searchResults(text: String) {
        // 検索フィールドが空ならフィルタなし
        if text.isEmpty {
            fetchedStaff.nsPredicate = nil
        } else {
            // nameアトリビュートにtextの文字列が含まれているかというフィルタを作成
            let namePredicate: NSPredicate = NSPredicate(format: "name contains %@", text)
            // staffエンティティにフィルタを適用(複数条件も適用可能)
            fetchedStaff.nsPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [namePredicate])
        }
    }
}
タイトルとURLをコピーしました