- Published on
SwiftUI-da Core Data va @FetchRequest bilan ishlash
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Bu videoda Core Data ko'rib chiqiladi. Bu — iPhone ichida saqlanadigan to'liq ma'lumotlar bazasi. Foydalanuvchi ilovani yopib qayta ochsa ham, ma'lumotlar o'chib ketmaydi.
Core Data vs UserDefaults
| UserDefaults / AppStorage | Core Data | |
|---|---|---|
| Maqsad | Kichik ma'lumotlar (ism, sozlama) | Katta hajmdagi ma'lumotlar bazasi |
| Saqlash | Kalit-qiymat | Jadval (entity) shaklida |
| Qidiruv va saralash | Yo'q | NSSortDescriptor, NSPredicate |
| Qachon ishlatish | Oddiy sozlamalar | Ro'yxatlar, ilovaning asosiy ma'lumotlari |
1-qadam: Yangi loyihada Core Data yoqish
Xcode-da yangi loyiha yaratishda: Use Core Data katagini belgilash. Apple avtomatik quyidagilarni yaratib beradi:
Persistence.swift— ma'lumotlar bazasini boshqaruvchi fayl.xcdatamodeld— entity va atributlar sxemasi- Tayyor
ContentView— oddiy misol
Arxitektura — asosiy komponentlar
PersistenceController — Singleton
struct PersistenceController {
// Singleton — butun ilova bo'ylab bitta instance
static let shared = PersistenceController()
// Preview uchun alohida instance
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
// Preview uchun soxta ma'lumotlar
for x in 0..<10 {
let newFruit = FruitEntity(context: viewContext)
newFruit.name = "Apple \(x)"
}
try? viewContext.save()
return result
}()
// NSPersistentContainer — ma'lumotlar bazasi o'zi
let container: NSPersistentContainer
init(inMemory: Bool = false) {
// Nom = .xcdatamodeld fayl nomi bilan bir xil bo'lishi shart
container = NSPersistentContainer(name: "CoreDataBootcamp")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores { _, error in
if let error = error {
// Development vaqtida crash qilish — xato bor bo'lsa darhol bildirish
// Production-da bu qatorni olib tashlash tavsiya etiladi
fatalError("Xato: \(error.localizedDescription)")
}
}
}
}
App.swift — viewContext-ni muhitga qo'yish
@main
struct CoreDataBootcampApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(
\.managedObjectContext,
persistenceController.container.viewContext
)
}
}
}
viewContext — ma'lumotlar bazasidagi aktiv ish maydoni. Barcha o'qish, yozish va o'chirish shu context orqali amalga oshiriladi.
2-qadam: FruitEntity yaratish
.xcdatamodeld faylida:
- Mavjud
Itementity-ni o'chirish - Add Entity →
FruitEntitydeb nomlash - Add Attribute →
name, turiString
Saqlash mumkin bo'lgan turlar: String, Int16/32/64, Double, Float, Bool, Date, UUID, Binary Data. Rasm yoki rang to'g'ridan-to'g'ri saqlanmaydi — Binary Data-ga konvertatsiya qilish kerak.
Xcode entity yaratilgandan so'ng, Xcode-ni qayta ishga tushirish tavsiya etiladi — ba'zan yangi entity avtomatik topilmaydi.
3-qadam: @FetchRequest — ma'lumotlarni olish
struct ContentView: View {
// muhitdan viewContext olish
@Environment(\.managedObjectContext) private var viewContext
// FruitEntity-larni ma'lumotlar bazasidan olish
@FetchRequest(
entity: FruitEntity.entity(),
sortDescriptors: [
NSSortDescriptor(
keyPath: \FruitEntity.name,
ascending: true // A → Z tartibda
)
]
) var fruits: FetchedResults<FruitEntity>
@State private var textFieldText: String = ""
var body: some View {
NavigationView {
VStack(spacing: 20) {
// Kiritish maydoni
TextField("Meva nomini kiriting...", text: $textFieldText)
.font(.headline)
.padding(.leading)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color(.systemGray5))
.cornerRadius(10)
.padding(.horizontal)
// Qo'shish tugmasi
Button {
addItem()
} label: {
Text("Qo'shish")
.font(.headline)
.foregroundColor(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.cornerRadius(10)
}
.padding(.horizontal)
// Mevalar ro'yxati
List {
ForEach(fruits) { fruit in
Text(fruit.name ?? "")
.onTapGesture {
updateItem(fruit: fruit)
}
}
.onDelete(perform: deleteItems)
}
.listStyle(PlainListStyle())
}
.navigationTitle("Mevalar ro'yxati")
.navigationBarItems(leading: EditButton())
}
.onAppear {
// Ilova ochilganda ma'lumotlar @FetchRequest orqali avtomatik yuklanadi
}
}
}
CRUD funksiyalari
Create — qo'shish
private func addItem() {
withAnimation {
// Yangi entity yaratish
let newFruit = FruitEntity(context: viewContext)
newFruit.name = textFieldText // textFieldText qiymatini saqlash
// Saqlash va textField-ni tozalash
saveItems()
textFieldText = ""
}
}
Read — o'qish
@FetchRequest bu ishni avtomatik bajaradi — fruits massivi doim yangilanib turadi. Qo'shimcha kod shart emas.
Update — yangilash
private func updateItem(fruit: FruitEntity) {
withAnimation {
// Entity-ni bevosita tahrirlash
let currentName = fruit.name ?? ""
let newName = currentName + "!" // Misol: "Apple" → "Apple!"
fruit.name = newName
// Saqlash
saveItems()
}
}
Delete — o'chirish
private func deleteItems(offsets: IndexSet) {
withAnimation {
// IndexSet-dan birinchi indexni olish
guard let index = offsets.first else { return }
let fruitEntity = fruits[index]
viewContext.delete(fruitEntity)
saveItems()
}
}
Save — saqlash (umumiy funksiya)
private func saveItems() {
do {
try viewContext.save()
} catch {
// Production-da bu yerda fatalError emas, xatoni log qilish tavsiya etiladi
fatalError("Saqlash xatosi: \(error.localizedDescription)")
}
}
NSSortDescriptor — tartiblash
// A → Z tartibda
NSSortDescriptor(keyPath: \FruitEntity.name, ascending: true)
// Z → A tartibda
NSSortDescriptor(keyPath: \FruitEntity.name, ascending: false)
// Bir nechta mezon bo'yicha
sortDescriptors: [
NSSortDescriptor(keyPath: \FruitEntity.name, ascending: true),
]
@FetchRequest va MVVM
Bu videoda barcha logika View ichida yozildi — bu boshlang'ich uchun tushunish osonroq. Lekin professional ilovalarda bu yondashuv MVVM arxitekturasiga to'g'ri kelmaydi: View-da faqat UI bo'lishi kerak, ma'lumot logikasi esa ViewModel-da bo'lishi kerak.
Bu video: View = UI + @FetchRequest + CRUD funksiyalari
MVVM usuli: View = faqat UI
ViewModel = @FetchRequest + CRUD funksiyalari
Keyingi videoda xuddi shu Core Data logikasi MVVM arxitekturasi bilan qayta yoziladi.
Xulosa
| Qadam | Nima qilinadi |
|---|---|
| Yangi loyiha | "Use Core Data" belgilash |
Persistence.swift | PersistenceController (Singleton) + container |
App.swift | viewContext-ni muhitga qo'yish |
.xcdatamodeld | Entity va atributlar yaratish |
| View | @Environment(\.managedObjectContext) + @FetchRequest |
| CRUD | addItem, deleteItems, updateItem, saveItems |
Core Data — katta hajmdagi ma'lumotlarni qurilmada doimiy saqlash uchun kuchli va samarali vosita. Sessiyalar orasida saqlanishi, saralash va filtrlash imkoniyatlari uni real ilovalarda asosiy ma'lumot ombori sifatida ishlatishga imkon beradi.