red*_*arz 2 core-data swift swiftui
我无法完成一项任务,在进入 时使用核心数据存储值TextField,并在进入视图时再次显示。是否可以?
我需要存储name和surname。为此,我创建了ProfileData数据模型,但找不到任何相关信息。关于如何使其正常工作。
请在代码下方找到:
import SwiftUI
import CoreData
struct ProfileView: View {
@State private var name: String = ""
@State private var surname: String = ""
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: ProfileData.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \ProfileData.name, ascending: true),
NSSortDescriptor(keyPath: \ProfileData.surname, ascending: true),
]
) var profile: FetchedResults<ProfileData>
@EnvironmentObject var profile1: ProfileData
var body: some View {
VStack {
HStack {
VStack {
HStack {
Text("Meno:")
.font(.headline)
.padding()
TextField("", text: $name, onCommit: {
self.profile1.name = self.name
try? self.managedObjectContext.save()})
.onAppear {
self.name = self.profile.name != nil ? "\(self.profile.name!)" : "Zadajte meno" //here I get error Value of type 'FetchedResults<ProfileData>' has no member 'name'
}
.onDisappear {
self.profile1.name = self.name
try? self.managedObjectContext.save()
}
} .padding(.leading, 37)
}
HStack {
Text("Priezvisko:")
.font(.headline)
.padding()
TextField("Zadajte priezvisko", text: $surname)
}
}
}
}
.navigationBarTitle(Text("Profil"))
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的 ProfileData+CoreClassData.swift:
import Foundation
import CoreData
@objc(ProfileData)
public class ProfileData: NSManagedObject {
}
Run Code Online (Sandbox Code Playgroud)
这是我的 ProfileData+CoreDataProperties.swifft
//
// ProfileData+CoreDataProperties.swift
// UcmMap
//
// Created by Jakub Adamec on 06/01/2020.
// Copyright © 2020 Jakub Adamec. All rights reserved.
//
//
import Foundation
import CoreData
extension ProfileData {
@nonobjc public class func fetchRequest() -> NSFetchRequest<ProfileData> {
return NSFetchRequest<ProfileData>(entityName: "ProfileData")
}
@NSManaged public var name: String?
@NSManaged public var surname: String?
}
Run Code Online (Sandbox Code Playgroud)
Here's full code:
import SwiftUI
import CoreData
@objc(ProfileData)
public class ProfileData: NSManagedObject, Identifiable {
public var id = UUID()
}
extension ProfileData {
@NSManaged public var name: String?
public var wrappedName: String{
get{name ?? "NoName"}
set{name = newValue}
}
@NSManaged public var surname: String?
public var wrappedSurname: String{
get{surname ?? "NoSurname"}
set{surname = newValue}
}
}
struct ProfileView: View {
@State private var name: String = ""
@State private var surname: String = ""
@Environment(\.managedObjectContext) var moc: NSManagedObjectContext // it will need you to add new examples of youre entities and save all changes
@FetchRequest(
entity: ProfileData.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \ProfileData.name, ascending: true),
NSSortDescriptor(keyPath: \ProfileData.surname, ascending: true),
]
) var profileList: FetchedResults<ProfileData>
//fetchRequest is a list of all objects off type ProfileData - saved and unsaved
var body: some View {
NavigationView{
List{
ForEach(profileList){profile in
NavigationLink(destination: profileUpdateView(profile: profile)){
Text("\(profile.wrappedName) \(profile.wrappedSurname) ")
}
}
HStack{
Image(systemName: "plus.circle.fill")
.foregroundColor(.green)
.imageScale(.large)
Button("add a new profile"){
let newProfile = ProfileData(context: self.moc)
newProfile.wrappedName = "Name"
newProfile.wrappedSurname = "Surname"
}
}
}
.navigationBarTitle(Text("Profile"))
.navigationBarItems(trailing: Button("save"){
if self.moc.hasChanges{
do{try self.moc.save()}
catch{print("Cant save changes: \(error)")}
}
})
}
}
}
struct profileUpdateView: View {
@ObservedObject var profile: ProfileData
var body: some View{
VStack {
HStack {
Text("Meno:")
.font(.headline)
.padding()
TextField("Zadajte meno", text: $profile.wrappedName)
}
HStack {
Text("Priezvisko:")
.font(.headline)
.padding()
TextField("Zadajte priezvisko", text: $profile.wrappedSurname)
}
}
}
}
struct ProfileView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newProfile = ProfileData(context: context)
newProfile.wrappedName = "Name"
newProfile.wrappedSurname = "Surname"
return ProfileView().environment(\.managedObjectContext, context)
}
}
Run Code Online (Sandbox Code Playgroud)
notice several things:
FetchRequest returns you a list of entities of type you define.
There may be one item, several items or there might be none.ForEach loop to show the result (most of the time).id to you're entity. Its not connected to CoreData, and every time FetchRequest gets new results, id will
change, but that's fine. The only purpose of it - is to let ForEach
know, which part of loop is connected with exactly object. Therefor
ForEach can change it and show you updatescodegen property of your entities in data model to manual/none. To do so open DataModel like, select your entity and go to data model inspector (right side of the screen). If you don't the compiler will create those files in compilation itself and this class will be defined twice.NSManagedObject type.TextField("Zadajte meno", text: $profile.wrappedName) The $ symbol is to make this property
wrapped @Binding. This means, all the changes made inside this
View will translate into this object instantly.@NSManaged property, because most of them have optional type like String?. I made a computed property
wrappedName to use it simply in Views.@ObservedObject wrapper in update View. Its like @State, but for classes. you use it when you want instantly update the View when this object changes. It also helps create a Binding. Your class must meet the ObservableObject protocol requirements, but NSManagedObject already does, so you don't need to worry about it. All @NSManaged attributes are already @Published.AppDelegate, create any test entities. But remember, saved changes will add to you're preview.moc.save(). It can throw an exception, so you must do it in try-catch. And its
a good practice to check, if there really are unsaved changes.祝你学习 SwiftUI 好运。使用 SwiftUI 和 CoreData 的信息并不多。尝试在hackingwithswift上检查它 ,有很多有用的信息。
| 归档时间: |
|
| 查看次数: |
2803 次 |
| 最近记录: |