Dữ liệu cốt lõi + SwiftUI

May 01 2023
Tại đây bạn có thể xem bài viết gốc Gần đây tôi phải xây dựng một ứng dụng bằng SwiftUI và CoreData. Tôi nghĩ rằng CoreData đã được sử dụng gần như bạn sẽ sử dụng nó với UIKit, nhưng dường như có một số khác biệt.
Ảnh của Michael Dziedzic trên Bapt

Ở đây bạn có thể xem bài viết gốc

Gần đây, tôi phải xây dựng một ứng dụng bằng SwiftUICoreData .

Tôi nghĩ rằng CoreData đã được sử dụng gần như bạn sẽ sử dụng nó với UIKit, nhưng dường như có một số khác biệt.

Hướng dẫn này nhằm mục đích tóm tắt kinh nghiệm của tôi khi sử dụng CoreData kết hợp với SwiftUI. Nếu tôi tìm thấy các khía cạnh khác, tôi sẽ thêm chúng vào hướng dẫn này.

Vì vậy, không có gì khó chịu, hãy bắt đầu.

Cài đặt

Đây là một phần khá đơn giản.

  • Nếu bắt đầu một dự án mới, bạn có thể chọn tùy chọn ' Use Core Data ' và ' Host in CloudKit ' nếu bạn muốn lưu dữ liệu người dùng của mình vào đám mây. Trong trường hợp này, XCode sẽ đảm nhận việc thiết lập dự án cho bạn. (Đối với phần CloudKit sẽ cần thực hiện thêm một số bước).
  • Nếu bạn đã có dự án, bạn sẽ cần tạo tệp Persistence.swift và tệp Swift nơi bạn khởi tạo ngăn xếp CoreData. (Bạn thậm chí có thể tạo một dự án mới theo bước trước đó và sao chép tệp Persistence.swift do XCode tạo vào dự án của bạn.

Bây giờ bạn đã có dự án của mình, để có thể sử dụng CoreData trong Chế độ xem của mình, bạn cần chuyển hệ managedObjectContextthống phân cấp chế độ xem xuống.

Thông thường, việc này được thực hiện trong tệp [appname]App.swift của bạn .

PersistenceController ( đây là một ví dụ ) là cấu trúc mà XCode tự động tạo cho bạn khi bạn bắt đầu một dự án mới với tùy chọn 'Sử dụng dữ liệu lõi' được chọn.

@main
struct ExampleApp: App {

  let persistenceController = PersistenceController.shared

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

Tuyệt vời, bây giờ bạn có thể tạo, đọc, cập nhật và xóa NSManagedObjects trong chế độ xem của mình.

Hoạt động với CoreData

Để vận hành với CoreData, bạn cần truy cập NSManagedObjectContext. Để làm như vậy, bạn có hai lựa chọn:

  • Sử dụng trình bao bọc Môi trường @ trong chế độ xem của bạn
  • @Environment(\.managedObjectContext) private var viewContext
    

    @EnvironmentObject private var persistenceController: PersistenceController
    

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

Để lưu NSManagedObject, trước tiên bạn cần kích hoạt nó và định cấu hình các thuộc tính của nó. Và sau đó lưu bối cảnh.

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

Tìm nạp đối tượng

Bây giờ là phần tìm nạp, đây là nơi tôi thấy khó khăn nhất. Hãy bắt đầu ngay.

Để tìm nạp các đối tượng trong SwiftUI, cách thuận tiện nhất là sử dụng trình bao bọc @FetchRequest hoặc @SectionedFetchRequest , trong mỗi Chế độ xem đơn lẻ mà bạn cần đọc từ CoreData.

Việc chuyển các đối tượng đã tìm nạp giữa các Chế độ xem sẽ phá vỡ các bản cập nhật tự động trong trường hợp bạn thêm, chỉnh sửa hoặc xóa các đối tượng. (Nếu bạn biết cách chuyển các đối tượng tìm nạp mà không vi phạm bản cập nhật, hãy cho tôi biết và tôi sẽ cập nhật hướng dẫn này)

Vì vậy, bạn cần thêm @FetchRequest trong mọi chế độ xem mà bạn cần các đối tượng CoreData và cập nhật tự động. Tôi biết nó hơi khó chịu nhưng nó sẽ đáng giá.

Vì vậy, với mã đã nói như sau:

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

Sử dụng @FetchRequest hoặc @SectionedFetchRequest bất cứ khi nào bạn thêm, cập nhật hoặc xóa một đối tượng, các dạng xem sẽ tự động được cập nhật.

Bây giờ, nếu bạn cần sử dụng @FetchRequest với NSPredicate có tham số được truyền từ Chế độ xem chính, tôi thấy rằng tùy chọn tiếp theo hoạt động tuyệt vời.

@FetchRequest
var objects: FetchedResults<Object>

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

Cập nhật đối tượng

Để cập nhật, NSManagedObjectbạn sẽ cần phải NSManagedObjectcập nhật, tìm nạp như được mô tả trước đó và cập nhật các thuộc tính của nó. Và sau đó lưu bối cảnh.

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

Để xóa một, NSManagedObjectbạn sẽ cần phải NSManagedObjectcập nhật, tìm nạp như được mô tả trước đó và xóa nó.

viewContext.delete(object)

Phần kết luận

Đó là tất cả những gì tôi đã khám phá cho đến nay về CoreData được sử dụng với SwiftUI. Hướng dẫn này sẽ được cập nhật liên tục.

Nếu bạn muốn đề xuất một cách tốt hơn để làm điều gì đó, hãy để lại nhận xét và tôi sẽ cập nhật hướng dẫn này với tùy chọn tốt nhất.

Tôi hy vọng tôi đã giúp bạn trong hành trình phát triển SwiftUI và iOS.

ĐỂ LẠI Vỗ tay nếu bạn thích bài viết này, tôi thực sự đánh giá cao nó.

Hẹn gặp lại bạn trong hướng dẫn tiếp theo!

Nếu bạn muốn hỗ trợ công việc của tôi và xem hướng dẫn này đang hoạt động, hãy xem BrainDump — Ghi chú & Viết .

Cảm ơn bạn