保存不断附加的自定义对象数组

Posted

技术标签:

【中文标题】保存不断附加的自定义对象数组【英文标题】:Saving an custom object array that is appended constantly 【发布时间】:2018-11-22 15:13:23 【问题描述】:

我对 Swift 和一般编码比较陌生。我现在正在努力磨练自己的技能,但正在组合一个简单的提醒应用程序。在我把故事板放在一起之前,我试图让后端工作,但我有必要的故事板元素来测试我的系统是否可以工作。

基本上,我试图保存一个包含自定义对象的数组,但这个数组被附加到用户完成的每个提醒添加中。这样每次应用程序打开时,数组都会包含上次的提醒。

这是我目前创建和附加列表的代码;

func createReminder() 
    let reminderAdd = Reminder(chosenReminderDescription: textRetrieve.text!, chosenReminderLength: 1)
    reminderList.append(reminderAdd)

    dump(reminderList)

这是目标代码;

class Reminder 

    var reminderDescription = "Require initalisation."
    var reminderLength = 1 // in days

    init (chosenReminderDescription: String, chosenReminderLength: Int) 
        reminderDescription = chosenReminderDescription
        reminderLength = chosenReminderLength
    


我将如何保存数组?

编辑: 这是我到目前为止添加的内容。

    override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let reminderAdd = Reminder(chosenReminderDescription: "Placeholder test", chosenReminderLength: 1)
    reminderList.append(reminderAdd)

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let entity = NSEntityDescription.entity(forEntityName: "Tasks", in: context)
    let newTask = NSManagedObject(entity: entity!, insertInto: context)

    newTask.setValue(reminderList, forKey: "taskName")

    do 
        try context.save()
     catch 
        print("Failed saving")
    

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Tasks")
    //request.predicate = NSPredicate(format: "age = %@", "12")
    request.returnsObjectsAsFaults = false
    do 
        let result = try context.fetch(request)
        for data in result as! [NSManagedObject] 
            print(data.value(forKey: "taskName"))
        

     catch 

        print("Failed")
    

我遇到了崩溃,我似乎还无法调试它。我相信这条线会导致崩溃,因为当我删除它时,应用程序启动正常。

let reminderAdd = Reminder(chosenReminderDescription: "Placeholder test", chosenReminderLength: 1)
    reminderList.append(reminderAdd)

有什么想法吗?

编辑 2: datamodel

那是数据模型,我不完全确定您将对象变成可编码的意思。再次感谢。

编辑 3:

ViewDidLoad

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let entity = NSEntityDescription.entity(forEntityName: "Tasks", in: context)
    let newTask = Tasks(entity: entity!, insertInto: context)

    newTask.setValue(reminderList, forKey: "taskName")

    do 
        try context.save()
     catch 
        print("Failed saving")
    

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Tasks")

    //request.predicate = NSPredicate(format: "age = %@", "12")
    request.returnsObjectsAsFaults = false
    do 
        let result = try context.fetch(request)
        for data in result as! [Tasks] 
            print(data.value(forKey: "taskName"))

        

     catch 

        print("Failed")
    

    dump(reminderList)

【问题讨论】:

您可以将其保存到.json 文件、sqlite 数据库、NSUserDefaults,将其发送到某个地方的云,或许多其他持久性替代方案。你试过什么? @Ian 不要使用 UserDefaults 来存储应用数据。 @rmaddy 我的意思是,我说可以,而不是应该,对吧? :) @IanMacDonald 我弄乱了 UserDefaults 但无法让它工作。今晚我会玩一玩,看看我能想出什么。 @IanMacDonald 我已经搞砸了核心数据,但我遇到了更多问题。我相信数据正在保存和获取,但是现在我已经尝试向数组添加一个值,以便它实际上可以保存不仅仅是一个空数组的东西,它会崩溃,请参阅我的编辑。谢谢,Sav。 【参考方案1】:

您可以使用 CoreData 创建一个实例并将其存储为内部数据库。 这些是一些很好的教程:

https://medium.com/xcblog/core-data-with-swift-4-for-beginners-1fc067cca707

https://www.raywenderlich.com/7569-getting-started-with-core-data-tutorial

编辑 2

正如您在这张图片中看到的, https://ibb.co/f1axcA 我在 coreData 中的列表是 [Notifica] 类型的,对象 Notifica 数组也是如此,要实现可编码,您应该这样做

public class Notifica: NSObject, NSCoding 

public required init?(coder aDecoder: NSCoder) 
    self.id = aDecoder.decodeObject(forKey: "id") as? Double
    self.type = aDecoder.decodeObject(forKey: "type") as? String
    self.idEvent = aDecoder.decodeObject(forKey: "idEvent") as? Int
    self.contactPerson = aDecoder.decodeObject(forKey: "contactPerson") as? People
    self.title = aDecoder.decodeObject(forKey: "title") as? String
    self.date = aDecoder.decodeObject(forKey: "date") as? String


public func encode(with aCoder: NSCoder) 
    aCoder.encode(id, forKey: "id")
    aCoder.encode(type, forKey: "type")
    aCoder.encode(idEvent, forKey: "idEvent")
    aCoder.encode(contactPerson, forKey: "contactPerson")
    aCoder.encode(title, forKey: "title")
    aCoder.encode(date, forKey: "date")


ecc..

另一件事是不要调用 NSManagedObject 并传递实体,但您应该像在 dataModel 中调用的那样命名 Tasks,如果您在 xcode 上键入 Tasks,它将为您找到创建的 NSManagedObject,然后您可以设置 taskName 的值

编辑 3

"&lt;Simple_Reminders.Reminder: 0x60400046da40&gt;" 表示存在 Reminder 对象!所以你救了它!提醒有两个变量: -reminderDescription 和 -reminderLength,所以改变你的代码

do 
    let result = try context.fetch(request)
    for data in result as! [Tasks] 
        print(data.value(forKey: "taskName"))

    

 catch 

    print("Failed")

有了这个

do 
    let result = try context.fetch(request)
    for data in result as! [Tasks] 
        print(data.value(forKey: "taskName"))
        if let reminders = data.value(forKey: "taskName") as? [Reminder] 
            for reminder in reminders 
                // Now you have your single object Reminder and you can print his variables
                print("Your reminder description is \(reminder. reminderDescription), and his length is \(reminder. reminderLength))"
            
        
    

 catch 

    print("Failed")

【讨论】:

我已经搞砸了核心数据,但我遇到了更多问题。我相信数据正在保存和获取,但是现在我已经尝试向数组添加一个值,以便它实际上可以保存不仅仅是一个空数组的东西,它会崩溃,请参阅我的编辑。谢谢,Sav。 let newTask = NSManagedObject(entity: entity!, insertInto: context) 首先你应该使用你的对象“Reminder”而不是 NSManagedObject,然后你应该将你的对象“Reminder”修改为可编码,我可以看看你是如何创建你的数据库 .xcdatamodeld 的吗? @FrancescoDestino 我再次编辑,显示数据模型。如何将 Reminder 对象更改为可编码对象? @FrancescoDestino 我相信这已经奏效了,但现在我只是从未包装的可选中崩溃了,因为 xcode 不接受?,只有!。我相信这是因为数组中没有设置任何值。 过去 30 分钟我一直在尝试修复:致命错误:在展开可选值时意外发现 nil,我无法更正此问题。你有什么建议?谢谢。

以上是关于保存不断附加的自定义对象数组的主要内容,如果未能解决你的问题,请参考以下文章

包含另一个自定义对象数组的自定义对象数组上的 NSPredicate

UserDefaults 自定义对象的自定义对象

iOS:如何保存在应用程序中创建的自定义对象

过滤数组列表或列表中的自定义对象[重复]

使用键更新数组中的自定义对象[重复]

Meteor:带有对象数组的自定义 AutoForm