@FetchRequest SwiftUI da — bu nima, Core Data tanlash va mexanizm

Muallif: IT Sectr Nashr etilgan: 2026-06-25 O'qish vaqti: 8 daq

@FetchRequest SwiftUI da — Core Data dan avtomatik ma’lumot tanlash uchun property wrapper, interfeysning reaktiv yangilanishi bilan. Wrapper filtrlash predikatlari va saralashlar bilan NSFetchRequest ni qabul qiladi, natija — NSManagedObject massivi — Core Data kontekstidagi har qanday o‘zgarishda avtomatik yangilanadi. Apple Developer Documentation (2025) ga ko‘ra, @FetchRequest SwiftUI muhitida managedObjectContext ni talab qiladi va dinamik predikatlarni qo‘llab-quvvatlaydi, Core Data va foydalanuvchi interfeysi o‘rtasida reaktiv aloqani ta’minlaydi.

Asosiy fikrlar

  • @FetchRequest — SwiftUI da Core Data ni reaktiv tanlash uchun property wrapper
  • Avtomatik yangilanish UI Core Data dagi yozuvlar qo‘shilganda, o‘chirilganda yoki o‘zgartirilganda
  • Predikatlar va saralashlar inicializatorda yoki property wrapper parametrlari orqali o‘rnatiladi
  • managedObjectContext View ierarxiyasida @Environment orqali mavjud bo‘lishi kerak
  • Dinamik predikatlar ish vaqtida filtrlash shartlarini o‘zgartirish imkonini beradi

SwiftUI da @FetchRequest nima?

@FetchRequest — Core Data dan FetchRequest yaratadigan va boshqaradigan SwiftUI property wrapper. Inicializatsiya vaqtida wrapper entity turini, saralash uchun NSSortDescriptor massivini va ixtiyoriy filtrlash uchun NSPredicate ni qabul qiladi. Natija belgilangan NSManagedObject turidagi obʻektlar massivi sifatida saqlanadi va persistentsiya qatlamidagi o‘zgarishlarda avtomatik yangilanadi.

@FetchRequest ning asosiy xususiyati reaktivlikdir. Core Data dagi ma’lumotlar o‘zgarganda (save, insert, delete, update), SwiftUI avtomatik ravishda qayta tanlashni amalga oshiradi va ushbu fetch request dan foydalanadigan barcha View larni qayta chizadi. Dasturchi qo‘lda refresh chaqirishi, NSManagedObjectContextDidSaveNotification ga obuna bo‘lishi yoki ma’lumotlarni qayta yuklashi shart emas. SwiftUI butun sinxronizatsiya siklini boshqaradi.

@FetchRequest ishlashi uchun SwiftUI muhitida @Environment(\.managedObjectContext) orqali NSManagedObjectContext mavjud bo‘lishi kerak. Kontekst odatda NSPersistentContainer yaratilgan ilova ildizidan uzatiladi. Standart namuna — Core Data stack ni sozlash va .environment() modifikatori orqali kontekstni uzatish uchun ViewModel yoki App strukturasidan foydalanish.

FetchRequest saralash va predikatlari

@FetchRequest tanlashni sozlash uchun bir necha parametrlarni qabul qiladi. SortDescriptors — yozuvlar tartibini belgilaydigan NSSortDescriptor massivi. Predicate — filtrlash uchun NSPredicate, masalan, faqat statusi „bajarilgan” bo‘lgan vazifalarni tanlash. Animation — ma’lumot o‘zgarishlarida ro‘yxatni yangilash uchun animatsiya.

Core Data predikatlari SQL ga o‘xshash ifoda formatidan foydalanadi: NSPredicate(format: „status == %@”, „completed”). Bir necha shartlarni AND, OR va NOT orqali birlashtirish mumkin. SortDescriptors tartibni belgilaydi: NSSortDescriptor(keyPath: \Task.dueDate, ascending: true). Bir necha maydon bo‘yicha saralash uchun deskriptorlar massivi uzatiladi — birinchi asosiy, qolganlari ikkilamchi sifatida qo‘llaniladi.

swift
struct TaskListView: View {
    @Environment(\.managedObjectContext) var viewContext

    @FetchRequest(
        sortDescriptors: [
            NSSortDescriptor(keyPath: \.Task.dueDate, ascending: true),
            NSSortDescriptor(keyPath: \.Task.priority, ascending: false)
        ],
        predicate: NSPredicate(format: "isCompleted == NO"),
        animation: .default
    )
    var tasks: FetchedResults<Task>

    var body: some View {
        List(tasks) { task in
            Text(task.title ?? "")
        }
    }
}

Misolda @FetchRequest barcha tugallanmagan vazifalarni (isCompleted == NO) tanlaydi, avval sana bo‘yicha (o‘sish), keyin ustuvorlik bo‘yicha (kamayish) saralaydi. FetchedResults<Task> — ForEach va List uchun massiv kabi harakat qiladigan avtomatik yangilanadigan kolleksiya. .default animatsiyasi o‘zgarishlarda yozuvlarning silliq paydo bo‘lishini/yo‘qolishini ta’minlaydi.

@FetchRequest List va dinamik ma’lumotlar bilan

@FetchRequest dinamik Core Data ro‘yxatlarini ko‘rsatish uchun List va ForEach bilan ideal birlashadi. Tanlash natijasi (FetchedResults) RandomAccessCollection protokoliga mos keladi, shuning uchun uni to‘g’ridan-to‘g’ri List va ForEach da ishlatish mumkin. Yozuvlar qo‘shilganda, o‘chirilganda yoki o‘zgartirilganda, ro‘yxat avtomatik ravishda animatsiya bilan qayta chiziladi.

Yozuvlarni o‘chirish uchun kontekstning delete metodidan foydalaniladi. Qo‘shish uchun — yangi NSManagedObject yaratish va save chaqirish. Barcha o‘zgarishlar @FetchRequest bilan birga ma’lumotlarning izchilligini ta’minlaydigan viewContext orqali amalga oshiriladi. Tahrirlash uchun muayyan Core Data ob’ekti uchun @ObservedObject yoki @Bindable ishlatiladi.

swift
struct TaskListWithActions: View {
    @Environment(\.managedObjectContext) var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \.Task.createdAt,
                                               ascending: false)]
    )
    var tasks: FetchedResults<Task>

    var body: some View {
        List {
            ForEach(tasks) { task in
                HStack {
                    Text(task.title ?? "")
                    Spacer()
                    Image(systemName: task.isCompleted
                               ? "checkmark.circle.fill"
                               : "circle")
                }
                .onTapGesture { toggleTask(task) }
            }
            .onDelete(perform: deleteTasks)
        }
        .toolbar {
            Button(systemImage: "qoʻshish") { addTask() }
        }
    }

    private func addTask() {
        let newTask = Task(context: viewContext)
        newTask.title = "New task \(tasks.count + 1)"
        newTask.createdAt = Date()
        try? viewContext.save()
    }

    private func toggleTask(_ task: Task) {
        task.isCompleted.toggle()
        try? viewContext.save()
    }

    private func deleteTasks(at offsets: IndexSet) {
        for index in offsets {
            viewContext.delete(tasks[index])
        }
        try? viewContext.save()
    }
}

Ushbu misol @FetchRequest bilan to‘liq CRUD ni namoyish etadi. Qo‘shish: kontekst orqali Task yaratish va save(). O‘chirish: kontekstda delete() va save(). Yangilash: xususiyatni toggle va save(). Har bir save() dan so‘ng @FetchRequest avtomatik ma’lumotlarni qayta so‘raydi va List animatsiya bilan yangilanadi. onDelete va onTapGesture modifikatorlari standart iOS o‘zaro ta’sirlarini ta’minlaydi.

Ish vaqtida dinamik predikatlar

@FetchRequest ish vaqtida o‘zgartirilishi mumkin bo‘lgan predicate parametri orqali dinamik predikatlarni qo‘llab-quvvatlaydi. Buning uchun o‘zgaruvchi-predikat bilan @FetchRequest yaratish va uni Binding orqali uzatish kerak. Foydalanuvchi filtrni o‘zgartirganda — masalan, vazifa kategoriyasini tanlaganda — predikat yangilanadi va tanlash avtomatik qayta ishga tushiriladi.

Dinamik predikatlar @State yoki @Published xususiyati orqali amalga oshiriladi, bu @FetchRequest inicializatoriga Binding sifatida uzatiladi. SwiftUI ushbu Binding ning o‘zgarishini kuzatadi va yangi predikat bilan NSFetchRequest ni qayta yaratadi, ro‘yxatni avtomatik yangilaydi.

@FetchRequest kod misollari

@FetchRequest bilan yozuvlarni tanlash uchun jurnal ilovasining to‘liq misolini ko‘rib chiqaylik. Qidiruv formasi dinamik predikatdan foydalanadi: matn kiritilganda FetchRequest avtomatik natijalarni yangilaydi, yozuvlarni sarlavha va mazmun bo‘yicha filtrlash orqali. Saralash — yaratilgan sana bo‘yicha, yangidan eskiga.

swift
struct JournalEntryView: View {
    @Environment(\.managedObjectContext) var viewContext
    @State private var searchText = ""

    private var searchPredicate: NSPredicate? {
        guard !searchText.isEmpty else { return nil }
        return NSPredicate(format: "title CONTAINS[c] %@", searchText)
    }

    @FetchRequest var entries: FetchedResults<JournalEntry>

    init(searchText: String) {
        let sort = [NSSortDescriptor(keyPath: \.JournalEntry.date,
                                           ascending: false)]
        let pred: NSPredicate? = searchText.isEmpty
            ? nil
            : NSPredicate(format: "title CONTAINS[c] %@ OR content CONTAINS[c] %@",
                          searchText, searchText)
        self._entries = FetchRequest(
            sortDescriptors: sort,
            predicate: pred,
            animation: .default
        )
    }

    var body: some View {
        List(entries) { entry in
            VStack(alignment: .leading) {
                Text(entry.title ?? "").font(.headline)
                Text(entry.content ?? "").font(.subheadline)
                    .lineLimit(2)
            }
        }
        .searchable(text: $searchText)
    }
}

Qidiruv bilan yozuvlar jurnali: searchable maydoniga matn kiritilganda NSPredicate title va content maydonlarida CONTAINS[c] (katta/kichik harflarga sezgir bo‘lmagan qidiruv) bilan yaratiladi. Init searchText ni qabul qiladi va mos predikat bilan FetchRequest yaratadi. Searchable modifikatori avtomatik searchText ni yangilaydi, @FetchRequest esa predikat o‘zgarishiga reaksiya beradi va ma’lumotlarni qayta so‘raydi.

Ko‘p filtrli murakkab stsenariylar uchun NSCompoundPredicate ni AND/OR mantig‘i bilan birlashtiring. @FetchRequest istalgan murakkablikdagi predikatlarni, shu jumladan munosabatlar bo‘yicha filtrlash uchun ichki osti so‘rovlarni (SUBQUERY) qo‘llab-quvvatlaydi. Ammo unutmang: murakkab predikatlar unumdorlikka ta’sir qiladi — katta ma’lumot to‘plamlari uchun (10 000 dan ortiq yozuv) Core Data indekslashdan foydalaning va fetchLimit orqali tanlashni cheklang.

Ko‘p beriladigan savollar

@FetchRequest ga managedObjectContext ni qanday uzatish mumkin?

Ildiz View ga @Environment(\.managedObjectContext) var viewContext qo‘shing va uni .environment(\.managedObjectContext, context) modifikatori orqali uzating. @FetchRequest dan foydalanadigan barcha bola View lar avtomatik kontekstni muhitdan oladi.

@FetchRequest ni View ni qayta yuklamasdan yangilash mumkinmi?

Ha, Core Data kontekstini o‘zgartiring: ob’ektni qo‘shing, o‘chiring yoki yangilang va save() ni chaqiring. @FetchRequest avtomatik qayta tanlashni amalga oshiradi va UI ni yangilaydi. Save() siz majburiy yangilash uchun viewContext.refreshAllObjects() dan foydalaning.

@FetchRequest va @SectionedFetchRequest o‘rtasidagi farq nima?

@FetchRequest tekis ob’ekt massivini qaytaradi. @SectionedFetchRequest natijalarni belgilangan key path bo‘yicha bo‘limlarga guruhlaydi, UITableView ning sectionNameKeyPath ga o‘xshash. Bo‘lim sarlavhalari bilan grouped ro‘yxatlar uchun @SectionedFetchRequest dan foydalaning.

@FetchRequest ni Relationship bilan qanday ishlatish mumkin?

Munosabatlar bo‘yicha filtrlash uchun nuqta notatsiyasidan foydalaning: NSPredicate(format: „category.name == %@”, „Work”). @FetchRequest SQLite da avtomatik JOIN ni amalga oshiradi. Tanlangan ob’ekt orqali munosabatga kirish uchun oddiy NSManagedObject xususiyatlaridan foydalaning.

@FetchRequest sahifalashni qo‘llab-quvvatlaydimi?

@FetchRequest to‘g’ridan-to‘g‘ri sahifalashni qo‘llab-quvvatlamaydi, chunki u reaktiv yangilanish bilan barcha yozuvlarni ko‘rsatish uchun mo‘ljallangan. Sahifalash uchun NSFetchRequest dan fetchLimit/fetchOffset bilan foydalaning va ro‘yxatni aylantirishda ma’lumotlarni qo‘lda yuklang.

Xulosa

  • @FetchRequest — SwiftUI da avtomatik reaktiv Core Data tanlash uchun property wrapper
  • Saralash NSSortDescriptor massivi bilan, filtrlash — NSPredicate bilan o‘rnatiladi
  • Avtomatik yangilanish Core Data kontekstidagi har qanday ma’lumot o‘zgarishida UI
  • managedObjectContext View ierarxiyasida @Environment orqali uzatiladi
  • Dinamik predikatlar predikat parametri bilan custom init orqali amalga oshiriladi
  • CRUD operatsiyalari ro‘yxatni avtomatik sinxronizatsiya bilan viewContext orqali bajariladi
  • Foydalaning @FetchRequest Core Data ko‘rsatish uchun, @SectionedFetchRequest — grouped ro‘yxatlar uchun

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing