core-data - 将 fetch req 和更新核心数据移动到模型
问题描述
如何将核心数据中的获取请求和更新值移动到模型中?
我有核心数据,比如说登录数据(userToken、isLogin 和 userType)。我需要在 2 视图中显示和更新这些数据。所以我需要多次创建更新、保存和获取请求。也许在登录视图和个人资料视图中。
是否可以使用模型从我的核心数据中更新、保存、删除和获取请求?
import SwiftUI
struct LoginView: View {
@State var isNavigationBarHidden: Bool = true
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [])
private var userData: FetchedResults<LoginData>
var body: some View {
ZStack {
Color.green
Button(action: {
setLogin()
}){
Text("Login Screen")
.foregroundColor(Color.black)
}
}
.navigationBarTitle("Hidden Title")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear {
self.isNavigationBarHidden = true
}
}
private func saveContext() {
do {
try viewContext.save()
} catch {
let error = error as NSError
fatalError("Unresolved error \(error)")
}
}
private func setLogin(){
let newUser = LoginData(context: viewContext)
newUser.isLogin = true
newUser.userToken = "JWT_TOKEN"
saveContext()
}
}
struct LoginView_Previews: PreviewProvider {
static var previews: some View {
LoginView()
}
}
我想把它放在我的模型中
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [])
private var userData: FetchedResults<LoginData>
private func saveContext() {
do {
try viewContext.save()
} catch {
let error = error as NSError
fatalError("Unresolved error \(error)")
}
}
private func setLogin(){
let newUser = LoginData(context: viewContext)
newUser.isLogin = true
newUser.userToken = "JWT_TOKEN"
saveContext()
}
我已经这样尝试了。
import SwiftUI
class UserDataModel: ObservableObject {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(sortDescriptors: [])
var loginData: FetchedResults<LoginData>
func saveContext() {
do {
try viewContext.save()
} catch {
let error = error as NSError
fatalError("Unresolved error \(error)")
}
}
func setLogin(){
let newUser = LoginData(context: viewContext)
newUser.isLogin = true
newUser.userToken = "JWT_TOKEN"
saveContext()
}
func setLogout(){
viewContext.delete(loginData[0])
saveContext()
}
}
但它告诉我错误。
Thread 1: Fatal error: Unresolved error Foundation._GenericObjCError.nilError
解决方案
为了让事情变得更简单,您可以在ObservableObject
.
class Publisher: ObservableObject {
static let shared: Publisher = Publisher()
let container: NSPersistentContainer
lazy var context = container.viewContext
@Published var isLoading: Bool = false
init() {
self.container = NSPersistentContainer(name: "CoreDataModelName")
container.loadPersistentStores { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error: \(error)")
}
}
}
}
然后将其设置为managedObjectContext
使用environment
视图修饰符:
尝试在视图层次结构中尽早设置它,以便其余视图可以访问它
struct ContentView: View {
@StateObject // or @ObservedObject
var publisher: Publisher = .shared
var body: some View {
Text("Hello World!")
// set `managedObjectContext` here
.environment(\.managedObjectContext, publisher.context)
}
}
然后,您应该可以跨多个视图访问视图上下文:
struct ChildView: View {
@Environment(\.managedObjectContext)
private var viewContext // Use the environment object `managedObjectContext`
@FetchRequest(sortDescriptors: [])
private var objects: FetchedResults<Object>
var body: some View {
Text(“Hello World!”)
}
private func saveContext() {
do {
try viewContext.save()
} catch {
let error = error as NSError
fatalError("Unresolved error \(error)")
}
}
private func saveObject() {
let object = Object(context: viewContext)
saveContext()
}
}
而且,还可以在您的ObservableObject
班级中访问:
extension Publisher {
/// Function used to update the current state of the app.
func update(_ perform: (() -> Void)? = nil) {
DispatchQueue.main.async { [self] in
isLoading = true
perform?()
isLoading = false
}
}
func saveContext() {
update { [self] in
do {
try context.save()
} catch {
let error = error as NSError
debugPrint(error.localizedDescription)
}
}
}
func save(object: Object) {
context.insert(object)
saveContext()
}
func delete(object: Object) {
context.delete(object)
saveContext()
}
}
推荐阅读
- javascript - running functions synchronously in firebase
- python - 如何使用 raspberry pi 和 python 扫描路由器的 RSSI 并根据值对它们进行排序?
- php - 检查两条路线(以纬度和经度表示)是否彼此相对
- angular - Angular 6 set 属性全局动态生成组件
- sql - How to declare a number variable where I can save th count of table in my loop
- c# - TFS 2018 Microsoft.VisualStudio.Services.WebApi.VssServiceResponseException:找不到页面
- acumatica - Acumatica REST API - StockItem - 如何在请求中使用具有特定产品 ID 的多个产品 ID
- java - 如何测试 Java 类是线程安全的?
- javascript - 交换变量的硬编码参数
- node.js - NodeJS + mongoose - 全局用户动态数据库