SwiftUI-এ @FetchRequest — এটি কী, Core Data ফেচিং এবং প্রক্রিয়া

লেখক: IT Sectr প্রকাশিত: 2026-06-25 পড়ার সময়: 8 মিনিট

SwiftUI-এ @FetchRequest — একটি property wrapper যা Core Data থেকে স্বয়ংক্রিয়ভাবে ডেটা ফেচ করে এবং রিঅ্যাকটিভভাবে UI আপডেট করে। Wrapper ফিল্টার প্রেডিকেট এবং সর্ট ডিসক্রিপ্টর সহ NSFetchRequest গ্রহণ করে, এবং ফলাফল — NSManagedObject-এর একটি অ্যারে — Core Data কনটেক্সটে যেকোনো পরিবর্তনে স্বয়ংক্রিয়ভাবে আপডেট হয়। Apple Developer Documentation (2025) অনুযায়ী, @FetchRequest-এর SwiftUI পরিবেশে managedObjectContext প্রয়োজন এবং এটি ডায়নামিক প্রেডিকেট সমর্থন করে, যা Core Data এবং ইউজার ইন্টারফেসের মধ্যে রিঅ্যাকটিভ সংযোগ নিশ্চিত করে।

মূল পয়েন্ট

  • @FetchRequest — SwiftUI-এ রিঅ্যাকটিভ Core Data ফেচিংয়ের জন্য property wrapper
  • অটো-আপডেট UI যখন Core Data-তে রেকর্ড যোগ, মুছে বা পরিবর্তন করা হয়
  • প্রেডিকেট এবং সর্ট ডিসক্রিপ্টর ইনিশিয়ালাইজারে বা property wrapper প্যারামিটারের মাধ্যমে সেট করা হয়
  • managedObjectContext View হায়ারার্কিতে @Environment-এর মাধ্যমে উপলব্ধ হতে হবে
  • ডায়নামিক প্রেডিকেট রানটাইমে ফিল্টার শর্ত পরিবর্তনের অনুমতি দেয়

SwiftUI-এ @FetchRequest কী?

@FetchRequest একটি SwiftUI property wrapper যা Core Data থেকে FetchRequest তৈরি এবং পরিচালনা করে। ইনিশিয়ালাইজেশনে, wrapper একটি entity type, সর্টিংয়ের জন্য NSSortDescriptor-এর অ্যারে এবং ফিল্টারিংয়ের জন্য একটি অপশনাল NSPredicate গ্রহণ করে। ফলাফল নির্দিষ্ট NSManagedObject টাইপের অবজেক্টের অ্যারে হিসেবে সংরক্ষিত হয় এবং persistence layer-এ পরিবর্তন হলে স্বয়ংক্রিয়ভাবে আপডেট হয়।

@FetchRequest-এর মূল বৈশিষ্ট্য হল রিঅ্যাকটিভিটি। যখন Core Data-তে ডেটা পরিবর্তিত হয় (save, insert, delete, update), SwiftUI স্বয়ংক্রিয়ভাবে পুনরায় ফেচ করে এবং এই fetch request ব্যবহার করে এমন সমস্ত Views পুনরায় রেন্ডার করে। ডেভেলপারকে ম্যানুয়ালি refresh কল করতে, NSManagedObjectContextDidSaveNotification-এ সাবস্ক্রাইব করতে বা ডেটা রিলোড করার প্রয়োজন নেই। SwiftUI সম্পূর্ণ সিঙ্ক্রোনাইজেশন চক্র পরিচালনা করে।

@FetchRequest কাজ করার জন্য, SwiftUI পরিবেশে @Environment(\.managedObjectContext)-এর মাধ্যমে একটি NSManagedObjectContext উপলব্ধ থাকা প্রয়োজন। কনটেক্সট সাধারণত অ্যাপ্লিকেশন রুট থেকে পাস করা হয়, যেখানে NSPersistentContainer তৈরি করা হয়। স্ট্যান্ডার্ড প্যাটার্ন হল Core Data স্ট্যাক কনফিগার করতে এবং .environment() মডিফায়ারের মাধ্যমে কনটেক্সট পাস করতে ViewModel বা App struct ব্যবহার করা।

FetchRequest-এর সর্টিং এবং প্রেডিকেট

@FetchRequest ফেচ কনফিগার করার জন্য বেশ কয়েকটি প্যারামিটার গ্রহণ করে। SortDescriptors — NSSortDescriptor-এর অ্যারে যা রেকর্ডের ক্রম নির্ধারণ করে। Predicate — ফিল্টারিংয়ের জন্য NSPredicate, উদাহরণস্বরূপ, শুধুমাত্র “সম্পূর্ণ” স্ট্যাটাসের টাস্ক ফেচ করা। Animation — ডেটা পরিবর্তনে তালিকা আপডেটের জন্য অ্যানিমেশন।

Core Data প্রেডিকেট SQL-সদৃশ এক্সপ্রেশনের ফরম্যাট ব্যবহার করে: NSPredicate(format: “status == %@”, “completed”)। AND, OR এবং NOT-এর মাধ্যমে একাধিক শর্ত একত্রিত করা যায়। SortDescriptors ক্রম নির্ধারণ করে: NSSortDescriptor(keyPath: \Task.dueDate, ascending: true)। একাধিক ফিল্ড দ্বারা সর্ট করতে, ডিসক্রিপ্টরের অ্যারে পাস করা হয় — প্রথমটি প্রাথমিক হিসেবে প্রয়োগ হয়, বাকিগুলো গৌণ হিসেবে।

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 ?? "")
        }
    }
}

উদাহরণে, @FetchRequest সব অসম্পূর্ণ টাস্ক (isCompleted == NO) ফেচ করে, প্রথমে তারিখ অনুসারে (ascending), তারপর প্রায়োরিটি অনুসারে (descending) সাজানো। FetchedResults<Task> একটি স্বয়ংক্রিয়ভাবে আপডেট হওয়া সংগ্রহ যা ForEach এবং List-এর জন্য অ্যারের মতো আচরণ করে। .default অ্যানিমেশন পরিবর্তনে রেকর্ডের মসৃণ উপস্থিতি/অদৃশ্যতা নিশ্চিত করে।

List এবং ডায়নামিক ডেটার সাথে @FetchRequest

@FetchRequest ডায়নামিক Core Data তালিকা প্রদর্শনের জন্য List এবং ForEach-এর সাথে পুরোপুরি মিলে যায়। ফেচ ফলাফল (FetchedResults) RandomAccessCollection প্রোটোকল মেনে চলে, তাই এটি List এবং ForEach-এ সরাসরি ব্যবহার করা যায়। রেকর্ড যোগ, মুছে বা পরিবর্তন করলে, তালিকা স্বয়ংক্রিয়ভাবে অ্যানিমেশনসহ পুনরায় রেন্ডার হয়।

রেকর্ড মুছতে, কনটেক্সট মেথড delete ব্যবহার করা হয়। রেকর্ড যোগ করতে, একটি নতুন NSManagedObject তৈরি করা হয় এবং save কল করা হয়। সব পরিবর্তন viewContext-এর মাধ্যমে করা হয়, যা @FetchRequest-এর সাথে ডেটা সামঞ্জস্য নিশ্চিত করে। এডিটিংয়ের জন্য, একটি নির্দিষ্ট Core Data অবজেক্টের জন্য @ObservedObject বা @Bindable ব্যবহার করা হয়।

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: "plus") { 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()
    }
}

এই উদাহরণটি @FetchRequest-এর সাথে সম্পূর্ণ CRUD প্রদর্শন করে। যোগ: কনটেক্সটের মাধ্যমে Task তৈরি এবং save()। মুছে ফেলা: কনটেক্সটে delete() এবং save()। আপডেট: প্রপার্টি টগল এবং save()। প্রতিটি save()-এর পর, @FetchRequest স্বয়ংক্রিয়ভাবে ডেটা পুনরায় ফেচ করে, এবং List অ্যানিমেটেডভাবে আপডেট হয়। onDelete এবং onTapGesture মডিফায়ারগুলি স্ট্যান্ডার্ড iOS ইন্টারঅ্যাকশন প্রদান করে।

@FetchRequest কোড উদাহরণ

আসুন রেকর্ড ফেচের জন্য @FetchRequest-সহ একটি সম্পূর্ণ জার্নাল অ্যাপ্লিকেশন উদাহরণ দেখি। সার্চ ফর্ম একটি ডায়নামিক প্রেডিকেট ব্যবহার করে: টেক্সট ইনপুট করলে, FetchRequest স্বয়ংক্রিয়ভাবে ফলাফল আপডেট করে, শিরোনাম এবং বিষয়বস্তু অনুসারে রেকর্ড ফিল্টার করে। সর্টিং তৈরি হওয়ার তারিখ অনুসারে, নতুন থেকে পুরাতন।

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)
    }
}

সার্চসহ জার্নাল: searchable ফিল্ডে টেক্সট ইনপুট করলে, title এবং content ফিল্ডে CONTAINS[c] (কেস-অসংবেদনশীল সার্চ) সহ একটি NSPredicate তৈরি হয়। Init searchText গ্রহণ করে এবং সংশ্লিষ্ট প্রেডিকেটসহ FetchRequest তৈরি করে। Searchable মডিফায়ার স্বয়ংক্রিয়ভাবে searchText আপডেট করে, এবং @FetchRequest প্রেডিকেট পরিবর্তনে সাড়া দিয়ে ডেটা পুনরায় ফেচ করে।

একাধিক ফিল্টারসহ আরও জটিল পরিস্থিতির জন্য, AND/OR লজিকের সাথে NSCompoundPredicate একত্রিত করুন। @FetchRequest যেকোনো জটিলতার প্রেডিকেট সমর্থন করে, যার মধ্যে relationship দ্বারা ফিল্টার করার জন্য নেস্টেড সাবকোয়েরি (SUBQUERY) অন্তর্ভুক্ত। তবে মনে রাখবেন: জটিল প্রেডিকেট পারফরম্যান্সকে প্রভাবিত করে — বড় ডেটাসেটের (10,000-এর বেশি রেকর্ড) জন্য, Core Data ইন্ডেক্সিং ব্যবহার করুন এবং fetchLimit-এর মাধ্যমে ফেচ সীমিত করুন।

রানটাইমে ডায়নামিক প্রেডিকেট

@FetchRequest predicate প্যারামিটারের মাধ্যমে ডায়নামিক প্রেডিকেট সমর্থন করে, যা রানটাইমে পরিবর্তন করা যায়। এর জন্য, একটি ভেরিয়েবল প্রেডিকেটসহ @FetchRequest তৈরি করা হয় এবং Binding-এর মাধ্যমে পাস করা হয়। যখন ব্যবহারকারী ফিল্টার পরিবর্তন করে — উদাহরণস্বরূপ, একটি টাস্ক ক্যাটাগরি নির্বাচন করে — প্রেডিকেট আপডেট হয় এবং ফেচ স্বয়ংক্রিয়ভাবে পুনরায় শুরু হয়।

ডায়নামিক প্রেডিকেট @State বা @Published প্রপার্টির মাধ্যমে বাস্তবায়িত হয়, যা @FetchRequest ইনিশিয়ালাইজারে Binding হিসেবে পাস করা হয়। SwiftUI এই Binding-এর পরিবর্তন ট্র্যাক করে এবং নতুন প্রেডিকেটসহ NSFetchRequest পুনরায় তৈরি করে, স্বয়ংক্রিয়ভাবে তালিকা আপডেট করে।

সচরাচর জিজ্ঞাসিত প্রশ্ন

@FetchRequest-এ managedObjectContext কীভাবে পাস করবেন?

রুট View-এ @Environment(\.managedObjectContext) var viewContext যোগ করুন এবং .environment(\.managedObjectContext, context) মডিফায়ারের মাধ্যমে পাস করুন। @FetchRequest ব্যবহার করে এমন সব চাইল্ড Views স্বয়ংক্রিয়ভাবে পরিবেশ থেকে কনটেক্সট পাবে।

@FetchRequest কি View রিলোড না করে আপডেট করা যায়?

হ্যাঁ, Core Data কনটেক্সট পরিবর্তন করুন: একটি অবজেক্ট যোগ, মুছে বা আপডেট করুন এবং save() কল করুন। @FetchRequest স্বয়ংক্রিয়ভাবে পুনরায় ফেচ করবে এবং UI আপডেট করবে। save() ছাড়া জোর করে আপডেটের জন্য, viewContext.refreshAllObjects() ব্যবহার করুন।

@FetchRequest এবং @SectionedFetchRequest-এর মধ্যে পার্থক্য কী?

@FetchRequest অবজেক্টের একটি ফ্ল্যাট অ্যারে রিটার্ন করে। @SectionedFetchRequest ফলাফলগুলিকে নির্দিষ্ট key path অনুসারে sectionNameKeyPath-সহ UITableView-এর মতো সেকশনে গ্রুপ করে। সেকশন হেডারসহ grouped তালিকার জন্য @SectionedFetchRequest ব্যবহার করুন।

Relationships-এর সাথে @FetchRequest কীভাবে ব্যবহার করবেন?

relationship দ্বারা ফিল্টার করতে, ডট নোটেশন ব্যবহার করুন: NSPredicate(format: “category.name == %@”, “Work”)। @FetchRequest স্বয়ংক্রিয়ভাবে SQLite-এ JOIN করে। নির্বাচিত অবজেক্টের মাধ্যমে relationship অ্যাক্সেস করতে, সাধারণ NSManagedObject প্রপার্টি ব্যবহার করুন।

@FetchRequest কি পেজিনেশন সমর্থন করে?

@FetchRequest সরাসরি পেজিনেশন সমর্থন করে না, কারণ এটি রিঅ্যাকটিভ আপডেটসহ সব রেকর্ড প্রদর্শনের জন্য ডিজাইন করা হয়েছে। পেজিনেশনের জন্য, fetchLimit/fetchOffset-সহ NSFetchRequest ব্যবহার করুন এবং তালিকা স্ক্রল করার সময় ম্যানুয়ালি ডেটা লোড করুন।

সারাংশ

  • @FetchRequest — SwiftUI-তে স্বয়ংক্রিয় রিঅ্যাকটিভ Core Data ফেচিংয়ের জন্য property wrapper
  • সর্টিং NSSortDescriptor-এর অ্যারে দ্বারা সেট করা হয়, ফিল্টারিং NSPredicate দ্বারা
  • অটো-আপডেট UI Core Data কনটেক্সটে যেকোনো ডেটা পরিবর্তনে
  • managedObjectContext View হায়ারার্কিতে @Environment-এর মাধ্যমে পাস করা হয়
  • ডায়নামিক প্রেডিকেট প্রেডিকেট প্যারামিটারসহ কাস্টম init-এর মাধ্যমে বাস্তবায়িত হয়
  • CRUD অপারেশন অটোমেটিক তালিকা সিঙ্ক্রোনাইজেশনসহ viewContext-এর মাধ্যমে করা হয়
  • ব্যবহার করুন @FetchRequest Core Data প্রদর্শনের জন্য, @SectionedFetchRequest grouped তালিকার জন্য

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন