에 입력 할 때 핵심 데이터와 함께 값을 저장 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"))
}
}
내 ProfileData + CoreClassData.swift는 다음과 같습니다.
import Foundation
import CoreData
@objc(ProfileData)
public class ProfileData: NSManagedObject {
}
그리고 여기 내 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?
}
다음은 전체 코드입니다.
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)
}
}
몇 가지 사항에 주목하십시오.
FetchRequest
정의한 유형의 엔티티 목록을 반환합니다. 하나의 항목, 여러 항목이있을 수도 있고 없을 수도 있습니다.ForEach
결과를 보여주는 루프가 필요합니다 (대부분).id
당신에게 엔티티를 추가했습니다 . CoreData에 연결되어 있지 않고 FetchRequest
새로운 결과를 얻을 때마다 id가 변경되지만 괜찮습니다. 그것의 유일한 목적은 ForEach
루프의 어느 부분이 정확히 객체와 연결되어 있는지 알려주는 것입니다 . 따라서 ForEach
변경하고 업데이트를 표시 할 수 있습니다.codegen
에 데이터 모델에서 개체의 속성을 manual/none
. 이렇게하려면 DataModel like를 열고 엔티티를 선택하고 데이터 모델 검사기로 이동합니다 (화면 오른쪽). 그렇지 않은 경우 컴파일러는 컴파일 자체에서 해당 파일을 생성하고이 클래스는 두 번 정의됩니다.NSManagedObject
유형의 개체를 만드는 유일한 방법 입니다.TextField("Zadajte meno", text: $profile.wrappedName)
. $
기호는이 속성을 래핑하는 것 @Binding
입니다. 즉, 내부의 모든 변경 사항 View
이 즉시이 개체로 변환됩니다.@NSManaged
대부분은 String?과 같은 선택적 유형이 있기 때문에 속성을 넣을 수 없습니다. wrappedName
뷰에서 간단히 사용하기 위해 계산 된 속성 을 만들었습니다 .@ObservedObject
업데이트보기에서 래퍼를 사용합니다 . 비슷 @State
하지만 수업 용입니다. View
이 개체가 변경 될 때 즉시 업데이트하고 싶을 때 사용합니다 . 또한 Binding
. 클래스는 ObservableObject
프로토콜 요구 사항을 충족해야 하지만 NSManagedObject
이미 충족 해야하므로 걱정할 필요가 없습니다. 모든 @NSManaged
속성이 이미 @Published
있습니다.AppDelegate
테스트 엔터티를 만듭니다. 그러나 저장된 변경 사항은 미리보기에 추가됩니다.moc.save()
. 예외가 발생할 수 있으므로 try-catch
. 그리고 실제로 저장되지 않은 변경 사항이 있는지 확인하는 것이 좋습니다.SwiftUI 학습에 행운을 빕니다. SwiftUI 및 CoreData 사용에 대한 정보가별로 없습니다. hackingwithswift 에서 확인해보세요 . 유용한 정보가 많이 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다