CoreData + SwiftUI

May 01 2023
Tutaj możesz zobaczyć oryginalny artykuł Ostatnio musiałem zbudować aplikację przy użyciu SwiftUI i CoreData. Myślałem, że CoreData był używany prawie tak, jak używałbyś go z UIKit, ale najwyraźniej istnieją pewne różnice.
Zdjęcie Michała Dziedzica na Unsplash

Tutaj możesz zobaczyć oryginalny artykuł

Ostatnio musiałem zbudować aplikację przy użyciu SwiftUI i CoreData .

Myślałem, że CoreData był używany prawie tak, jak używałbyś go z UIKit, ale najwyraźniej istnieją pewne różnice.

Ten przewodnik ma na celu podsumowanie moich doświadczeń związanych z używaniem CoreData w połączeniu z SwiftUI. Jeśli znajdę inne aspekty, dodam je do tego poradnika.

Więc bez zbędnych ceregieli zaczynajmy.

Organizować coś

To całkiem prosta część.

  • Jeśli rozpoczynasz nowy projekt, możesz zaznaczyć opcję „ Użyj podstawowych danych ” i „ Hostuj w CloudKit ”, jeśli chcesz zapisywać dane użytkowników w chmurze. W takim przypadku XCode zajmie się konfiguracją projektu za Ciebie. (W przypadku części CloudKit konieczne będzie wykonanie kilku dodatkowych kroków).
  • Jeśli masz już projekt, musisz utworzyć plik Persistence.swift i plik Swift, w którym zainicjujesz stos CoreData. (Możesz nawet utworzyć nowy projekt po wykonaniu poprzedniego kroku i skopiować plik Persistence.swift wygenerowany przez XCode do swojego projektu.

Teraz, gdy masz już swój projekt, aby móc korzystać z CoreData w swoich widokach, musisz przekazać managedObjectContexthierarchię widoków w dół.

Zwykle odbywa się to w pliku [nazwa aplikacji]App.swift .

PersistenceController ( tutaj przykład ) to struktura, którą XCode generuje automatycznie, gdy rozpoczynasz nowy projekt z zaznaczoną opcją „Użyj danych podstawowych”.

@main
struct ExampleApp: App {

  let persistenceController = PersistenceController.shared

  var body: some Scene {
    WindowGroup {
      ContentView()
        .environmentObject(persistenceController)
        .environment(\.managedObjectContext, persistenceController.container.viewContext)
    }
  }
}

Świetnie, teraz możesz tworzyć, odczytywać, aktualizować i usuwać obiekty NSManagedObjects w swoich widokach.

Praca z CoreData

Aby pracować z CoreData, musisz uzyskać dostęp do NSManagedObjectContext. Aby to zrobić, masz dwie możliwości:

  • Używanie opakowania @ Environment w swoich widokach
  • @Environment(\.managedObjectContext) private var viewContext
    

    @EnvironmentObject private var persistenceController: PersistenceController
    

do {
  if container.viewContext.hasChanges {
    try container.viewContext.save()
  }
} catch {
  print(error)
}

Aby zapisać NSManagedObject, musisz najpierw utworzyć jego instancję, a następnie skonfigurować jego właściwości. A następnie zapisz kontekst.

let note = Note(context: container.viewContext)
note.id = id
note.text = text
note.folder = folder
note.creationDate = Date()
saveContext()

Pobieranie przedmiotów

Teraz wciągająca część, tutaj znalazłem najwięcej trudności. Zacznijmy od razu.

Aby pobrać obiekty w SwiftUI, najwygodniejszym sposobem na to jest użycie opakowań @FetchRequest lub @SectionedFetchRequest , w każdym widoku, który musisz odczytać z CoreData.

Przekazywanie pobranych obiektów między widokami przerwie automatyczne aktualizacje w przypadku dodania, edycji lub usunięcia obiektów. (Jeśli znasz sposób przekazywania obiektów pobierania bez przerywania aktualizacji, daj mi znać, a zaktualizuję ten przewodnik)

Musisz więc dodać @FetchRequest w każdym widoku, którego potrzebujesz obiektów CoreData i automatycznych aktualizacji. Wiem, że to trochę denerwujące, ale będzie tego warte.

Tak więc, powiedziawszy, kod jest następujący:

@FetchRequest(entity: \Object.type,
              sortDescriptors: [NSSortDescriptor],
              predicate: NSPredicate,
              animation: .default)
var objects: [Object]

@SectionedFetchRequest(entity: \Object.type,
                         sectionIdentifier: \Object.property,
                         sortDescriptors: [NSSortDescriptor],
                         predicate: NSPredicate,
                         animation: .default)
var sections: SectionedFetchResults<YourSectionType, Object>

List(sections) { section in
  Section(section.id) {
    ForEach(section) { object in
      // Configure your view with the object
    }
  }
}

Używając @FetchRequest lub @SectionedFetchRequest wszędzie tam, gdzie dodajesz, aktualizujesz lub usuwasz obiekt, widoki są aktualizowane automatycznie.

Teraz, jeśli potrzebujesz użyć @FetchRequest z NSPredicate , który ma parametr przekazany z nadrzędnego widoku, odkryłem, że następna opcja działa cudownie.

@FetchRequest
var objects: FetchedResults<Object>

init(id: ID) {
  _objects = FetchRequest<Object>(predicate: NSPredicate(format: "id == %@", id))
}

Aktualizowanie obiektów

Aby zaktualizować, NSManagedObjectmusisz zaktualizować NSManagedObject, pobrać zgodnie z wcześniejszym opisem i zaktualizować jego właściwości. A następnie zapisz kontekst.

note.text = newText
note.folder = newFolder
saveContext()

Aby usunąć, NSManagedObjectmusisz zaktualizować NSManagedObject, pobrać zgodnie z wcześniejszym opisem i usunąć.

viewContext.delete(object)

Wniosek

To wszystko, co do tej pory odkryłem na temat CoreData używanego z SwiftUI. Ten przewodnik będzie stale aktualizowany.

Jeśli chcesz zasugerować lepszy sposób na zrobienie czegoś, zostaw komentarz , a ja zaktualizuję ten przewodnik o najlepszą opcję.

Mam nadzieję, że pomogłem ci w podróży z SwiftUI i programowaniem na iOS.

ZOSTAW KLASK, jeśli podobał Ci się ten artykuł, naprawdę to doceniam.

Do zobaczenia w kolejnym poradniku!

Jeśli chcesz wesprzeć moją pracę i zobaczyć ten przewodnik w akcji, sprawdź BrainDump — Notatki i pisanie .

Dziękuję