如何使用NSUserDefaults Swift存储自定义对象数组

时间:2015-07-14 18:41:23

标签: ios swift storing-data

我是一名新手程序员,已经开始学习Swift来制作应用程序。

所以我的问题是:"如何使用NSUserDefaults"存储我的对象数组。最初,我在看this question posted on stack overflow。但是,我并不完全理解他们是如何做到的。在youtube上搜索后确实没有成功,我别无选择,只能询问有关堆栈溢出的问题。 (我犹豫不决,因为人们常常把我的问题投反对票,因为我是一个初学者问愚蠢的问题)

所以这里。

我正在使用swift创建一个待办事项列表。我有一个名为任务管理器的主类,它包含一个Task对象数组。

任务管理器(功能)

  • 包含任务数组
  • 使用NSUserDefaults保存和加载数据以存储任务

任务(功能)

  • 存储任务的名称和说明
  • 不确定是否还有其他内容

所以现在,在看了几个在线教程之后,这就是我所拥有的。 (它没有用)

任务管理器:原始代码

//
//  TaskManager.swift
//  ToDoList
//
//  Created by Ronak Shah on 7/5/15.
//  Copyright (c) 2015 com.ShahIndustries. All rights reserved.
//

import UIKit

var taskMgr : TaskManager = TaskManager()


class TaskManager: NSObject{
    var tasks: [Task]? = [Task]()
    var time = 1 //debug, ignore

    override init(){
        super.init()

        let taskData = NSUserDefaults.standardUserDefaults().objectForKey("tasks") as? NSData

        if let taskData = taskData {
            let taskArray = NSKeyedUnarchiver.unarchiveObjectWithData(taskData) as? [Task]

            if let taskArray = taskArray {
                tasks = taskArray
            }

        }
    }

    func addTask(taskName : String, taskDescription : String){
        var newTask = Task(taskName: taskName , taskDescription: taskDescription)

        tasks!.append(newTask)

    }

    func getTaskAtIndex(index: Int) ->Task {
        return tasks![index]
    }


    func saveData() {
        let ud = NSUserDefaults.standardUserDefaults()
        ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(taskMgr), forKey: "tasks")
    }

    required init(coder aDecoder: NSCoder) {
        if let dataTasks = aDecoder.decodeObjectForKey("tasks") as? [Task] {
            self.tasks = dataTasks
        }

    }

    func encodeWithCoder(aCoder: NSCoder) {
        if let tasks = self.tasks {
            aCoder.encodeObject(tasks, forKey: "tasks")
        }
    }

    func loadData() {
        let ud = NSUserDefaults.standardUserDefaults()
        if let data = ud.objectForKey("tasks") as? NSData {
            //not sure how to get the data
        }
    }
}

任务:原始代码

//
//  Task.swift
//  ToDoList
//
//  Created by Ronak Shah on 7/5/15.
//  Copyright (c) 2015 com.ShahIndustries. All rights reserved.
//

import Foundation

class Task :NSObject{
    var name : String?
    var desc : String?

    init (taskName : String, taskDescription : String){
        self.name = taskName
        self.desc = taskDescription
    }
    required init(coder aDecoder: NSCoder) {
        if let dataDesc = aDecoder.decodeObjectForKey("desc") as? String {
            self.desc = dataDesc
        }

        if let dataTitle = aDecoder.decodeObjectForKey("name") as? String {
            self.name = dataTitle
        }
    }

    func encodeWithCoder(aCoder: NSCoder) {
        if let name = self.name {
            aCoder.encodeObject(name, forKey: "name")
        }

        if let desc = self.desc {
            aCoder.encodeObject(desc, forKey: "desc")
        }
    }
}

那么我如何存储我的任务数组(任务管理器中的命名任务)?

1 个答案:

答案 0 :(得分:0)

文档说:

  

对于NSArray和NSDictionary对象,其内容必须是属性列表对象

属性列表类型中有NSData个。要将自定义对象转换为NSData,您必须将其序列化。

您正尝试在TaskTaskManager对象上实施归档步骤,这会增加复杂性。实现目标的最简单方法是将NSData对象归档(转换为Task)并将其添加到数组中,然后再保存为默认值。为此,您必须将类型tasks的{​​{1}}数组转换为[Task]类型的数组。它看起来像这样。

[NSData]

当您获得数据时,您必须将func saveData() { let tasksAsData = tasks.map { task in return NSKeyedArchiver.archivedDataWithRootObject(task) } let ud = NSUserDefaults.standardUserDefaults() ud.setObject(tasksAsData, forKey: "tasks") } 个对象转换为NSData个。您可以通过以下方式完成此操作。

Task
你去吧!我想你可以从这里拿走它。

作为旁注,我建议不要将func loadData() { let ud = NSUserDefaults.standardUserDefaults() if let data = ud.objectForKey("tasks") as? [NSData] { tasks = data.map { data in return NSKeyedUnarchiver.unarchiveObjectWithData(data) } } } 用于此目的。默认值是一种保存(通常)非结构化数据的简单方法。当您为任务添加更多属性时,可能会变得很麻烦(您可能会对NSUserDefaultsimagedate等内容进行序列化。它不节省空间,也不快。我建议您查看其他方式在iOS上保留数据,例如locationSQLiteCore Data或许多其他方式。