Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用swiftui将textfield存储到核心数据中_Swift_Core Data_Swiftui - Fatal编程技术网

如何使用swiftui将textfield存储到核心数据中

如何使用swiftui将textfield存储到核心数据中,swift,core-data,swiftui,Swift,Core Data,Swiftui,我无法完成在输入TextField时使用核心数据存储值,并在输入视图时再次显示的任务。可能吗 我需要储存姓名。为此,我创建了ProfileData数据模型,但找不到任何相关信息。关于如何使其正常工作 请查看以下代码: import SwiftUI import CoreData struct ProfileView: View { @State private var name: String = "" @State private var surname: String =

我无法完成在输入TextField时使用核心数据存储值,并在输入视图时再次显示的任务。可能吗

我需要储存姓名。为此,我创建了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+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可以更改它并向您显示更新 不要忘记将数据模型中实体的codegen属性更改为manual/none。要这样做,请像打开DataModel一样,选择您的实体并转到屏幕右侧的data model inspector。如果不这样做,编译器将在编译本身中创建这些文件,并且该类将被定义两次。 如果您想创建您的类型的新对象-您需要使用MOC。这是创建NSManagedObject类型对象的唯一方法。 在TextField中,可以放置BindableObject。你试图使用@State来达到这个目的,但你并不需要它。你可以修改普通的 objects属性,如下所示:TextFieldZadajte meno,text:$profile.wrappedName$符号用于创建此属性 包装@装订。这意味着,所有在这个 视图将立即转换为该对象。 您不能只放置@NSManaged属性,因为大多数属性都有可选类型,比如String?。我做了一个计算财产 wrappedName可以简单地在视图中使用它。 我在更新视图中使用@ObservedObject包装器。它类似于@State,但用于类。当您希望在该对象更改时立即更新视图时,可以使用它。它还有助于创建绑定。您的类必须满足ObserveObject协议要求,但是NSManagedObject已经满足了,所以您不必担心它。所有@NSManaged属性都已@Published。 即使使用CoreData,也有一种方法可以使用Canvas。只需从AppDelegate获取上下文,创建任何测试实体。但请记住,保存的更改将添加到预览中。 最后,您需要使用moc.save保存所有更改。它可能引发异常,因此您必须在try-catch中执行此操作。及其 检查是否确实存在未保存的更改是一种很好的做法。 祝你学习SwiftUI好运。使用SwiftUI和CoreData的信息并不多。请尝试查看,这里有很多有用的信息。

以下是完整的代码:

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可以更改它并向您显示更新 不要忘记将数据模型中实体的codegen属性更改为manual/none。要这样做,请像打开DataModel一样,选择您的实体并转到屏幕右侧的data model inspector。如果不这样做,编译器将在编译本身中创建这些文件,并且该类将被定义两次。 如果您想创建您的类型的新对象-您需要使用MOC。这是创建NSManagedObject类型对象的唯一方法。 在TextField中,可以放置BindableObject。你试图使用@State来达到这个目的,但你并不需要它。你可以修改普通的 objects属性,如下所示:TextFieldZadajte meno,text:$profile.wrappedName$符号用于创建此属性 包装@装订。这意味着,所有在这个 视图将立即转换为该对象。 您不能只放置@NSManaged属性,因为大多数属性都有可选类型,比如String?。我做了一个计算财产 wrappedName可以简单地在视图中使用它。 我在更新视图中使用@ObservedObject包装器。它类似于@State,但用于类。当您希望在该对象更改时立即更新视图时,可以使用它。它还有助于创建绑定。您的类必须满足ObserveObject协议要求,但是NSManagedObject已经满足了,所以您不必担心它。所有@NSManaged属性都已@Published。 即使使用CoreData,也有一种方法可以使用Canvas。只需从AppDelegate获取上下文,创建任何测试实体。但请记住,保存的更改将添加到预览中。 最后,你需要做一件事 使用moc.save保存所有更改。它可能引发异常,因此您必须在try-catch中执行此操作。及其 检查是否确实存在未保存的更改是一种很好的做法。
祝你学习SwiftUI好运。使用SwiftUI和CoreData的信息并不多。尝试查看它,这里有很多有用的信息。

您在这里更新profile1,但它保存在哪里?另外,您已经声明了一个获取请求,但您没有使用它,这是故意的吗?我现在没有使用它,因为首先我想关注的是应用程序已启动,并且没有存储任何名称和姓氏。我理解你所说的保存是什么意思,但在我发布这个问题时,我找不到更多的东西可以用swiftui保存包含核心数据的文本字段,所以我只能准备这些。将代码更新为最新版本。你在这里更新profile1,但它保存在哪里?另外,您已经声明了一个获取请求,但您没有使用它,这是故意的吗?我现在没有使用它,因为首先我想关注的是应用程序已启动,并且没有存储任何名称和姓氏。我理解你所说的保存是什么意思,但在我发布这个问题时,我找不到更多关于使用swiftui保存包含核心数据的文本字段的内容,所以我只能准备这些内容。将代码更新为最新版本。您好@Aspid,首先感谢您的回答。我试图实现您的代码,但几乎没有错误:1。使用预览时,我无法生成ProfileView,因为函数“fetchRequest”未标记为dynamic 2。我删除了CoreData数据模型,因为有一个错误,它是@objcProfileData的副本,正确吗?3。我将此视图作为内容视图中的选项卡,当我模拟应用程序并单击此选项卡时,应用程序崩溃@UIApplicationMain class AppDelegate:UIResponder,UIApplicationLegate{错误线程1:致命错误:UnsafeRawBufferPointer计数为负数。这可能是因为AppDelegate和SceneDelegate包含从我设置项目使用CoreData时自动生成的方法吗?@redears最后一个错误是Xcode无法加载数据模型,因此无法访问您r实体。获取数据模型并检查是否在AppDelegate文件中加载了正确的模型,但当我获取它时,它与您的@objc ProfileData代码冲突,它说它是重复的,以修复“fetchRequest”重复-我刚刚删除了此函数。我不确定,但我相信NSManagedObject已经有了该函数。至少此错误是只在画布中出现,不会出现在模拟器中。如果“ProfileData”出现重复的类定义错误-您忘记将DataModel中实体的“codeGen”属性更改为manual/noneHello@Aspid,首先感谢您的回答。我已经尝试实现了您的代码,但出现了一些错误:1.使用预览时,我无法生成ProfileView替换的函数“fetchRequest”未标记为dynamic 2。我删除了CoreData数据模型,因为出现了一个错误,即它是@objcProfileData的副本,正确吗?3.我将此视图作为内容视图中的选项卡,当我模拟应用程序并单击此选项卡时,应用程序崩溃@UIApplicationMain class AppDelegate:UIResponder,UIAp应用程序代理{错误线程1:致命错误:UnsafeRawBufferPointer计数为负数。这可能是因为AppDelegate和SceneDelegate包含从我设置项目使用CoreData时自动生成的方法吗?@redears最后一个错误是Xcode无法加载数据模型,因此无法访问您r实体。获取数据模型并检查是否在AppDelegate文件中加载了正确的模型,但当我获取它时,它与您的@objc ProfileData代码冲突,它说它是重复的,以修复“fetchRequest”重复-我刚刚删除了此函数。我不确定,但我相信NSManagedObject已经有了该函数。至少此错误是PPE仅在画布中显示,不会出现在模拟器中。如果“ProfileData”出现重复的类定义错误,则会忘记将DataModel中实体的“codeGen”属性更改为手动/无