使用NSCore和NSKeyedArchiver与SWIFT

时间:2016-01-19 21:20:04

标签: swift class nsuserdefaults nscoder

我一直试图在我的应用上获取持久数据,以获得用户条目的历史记录。在我将数据存储到数组后,我想将其存档,并且在我取消存档之后,我得到了奇怪的价值,而不是我想要看到的。

以下是我存储数据的课程

导入基金会

class MyHistory: NSObject, NSCoding {
    var kicksNumber: Int
    var durationNumber: Int


     init(kicksNumber: Int,durationNumber: Int) {
        self.kicksNumber = kicksNumber
        self.durationNumber = durationNumber
    }

    required init(coder decoder: NSCoder) {
        kicksNumber = decoder.decodeObjectForKey("kicksNumber") as! Int
        durationNumber = decoder.decodeObjectForKey("durationNumber") as! Int
    }


    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(self.kicksNumber, forKey: "kicksNumber")
        coder.encodeObject(self.durationNumber, forKey: "durationNumber")   
    }
}

然后这是我的课程,在那里我发生了事情,以及我在测试保存和加载过程的地方。

class Kicks: UIViewController {

    var myHistoryArray: [MyHistory] = []
    var currentMyHistory: MyHistory!
    var newHistory = [MyHistory]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background13.png")!)


        let defaults = NSUserDefaults.standardUserDefaults()

        if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
            newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
            //print("this is archived ", newHistory[0])

        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    var count = 0 as Int
    var countKicks = 0 as Int
    var kickReached = false as Bool
    var pressedOnce = true as Bool
    var timer = NSTimer()
    var test: MyHistory!

    @IBOutlet var timerLabel: UITextField!
    @IBOutlet var kicksLabel: UITextField!


    @IBAction func kickButton() {
        //currentMyHistory.kicksNumber = 5


        if pressedOnce {
            pressedOnce = false
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counter"), userInfo: nil, repeats: true)
        } else if kickReached {

            //  let date = NSDate()
            //  let calendar = NSCalendar.currentCalendar()
            // let timer_total = calendar.components([ .Hour, .Minute, .Second], fromDate: date)
        } else if !pressedOnce {
            countKicks++
            kicksLabel.text = "\(countKicks)"
            if countKicks == 10 {
                kickReached = true
                timer.invalidate()
                congratsAlert()

                currentMyHistory = MyHistory(kicksNumber: 5, durationNumber: 10)
                print("this is currentMyHistory", currentMyHistory.kicksNumber )

                myHistoryArray.append(currentMyHistory)
                test = myHistoryArray[0]
                print("this is myHistoryArray0",  test.kicksNumber)
                //save data
                let savedData = NSKeyedArchiver.archivedDataWithRootObject(myHistoryArray)
                let defaults = NSUserDefaults.standardUserDefaults()
                defaults.setObject(savedData, forKey: "MyHistory")
                //load data
                //let defaults = NSUserDefaults.standardUserDefaults()

               // let person = people[indexPath.item]
               //let historyUnarchived = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? [MyHistory]
         //       let data1 = NSUserDefaults.standardUserDefaults().objectForKey("myHistoryArray")
                print("this is unrachived",newHistory[0])
                clear()
            }
        }
    }

    // save countKicks, count, and stamp i
    func congratsAlert() {
        let alert = UIAlertController(title: "Congratulation", message: "Yay!!! Angelina kicked 10 times in less than 2 hours.",preferredStyle: .Alert)

        let okAction = UIAlertAction(title: "Ok",style: .Default,handler:{(action:UIAlertAction) -> Void in})
        alert.addAction(okAction)

        presentViewController(alert,animated: true,completion: nil)
    }

    func clear() {
        count = 0
        countKicks = 0
        kickReached = false
        pressedOnce = true
        timerLabel.text = "00:00:0\(count)"
        kicksLabel.text = "\(countKicks)"
    }

    func counter() {
        ++count
        let (hour,minutes,seconds) = secondsToHoursMinutesSeconds(count)

        if seconds < 10 && minutes < 10 {
            timerLabel.text = "0\(hour):0\(minutes):0\(seconds)"
        } else if seconds > 9 && minutes < 10 {
            timerLabel.text = "0\(hour):0\(minutes):\(seconds)"
        } else if seconds > 9 && minutes > 9 {
            timerLabel.text = "0\(hour):\(minutes):\(seconds)"
        } else if seconds < 10 && minutes > 9 {
            timerLabel.text = "0\(hour):\(minutes):0\(seconds)"
        }
    }

    func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
        return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
    }
    /*

    func savePlaces() {
        let placesArray = [myHistory(kicksNumber: 420, durationNumber: 89)]
        let placesData = NSKeyedArchiver.archivedDataWithRootObject(placesArray)
        NSUserDefaults.standardUserDefaults().setObject(placesData, forKey: "kicks")
    }

    func loadPlaces() {
    let placesData = NSUserDefaults.standardUserDefaults().objectForKey("kicks") as? NSData

    if let placesData = placesData {
    let placesArray = NSKeyedUnarchiver.unarchiveObjectWithData(placesData) as? [myHistory]

    if let placesArray = placesArray {
    // do something…
    }

    }
    }*/
}

我的输出是这样的:

这是currentMyHistory 5

这是myHistoryArray0 5

这是未经授权的

来自调试器的消息:由于信号15而终止

为什么未归档是一种奇怪的价值?

1 个答案:

答案 0 :(得分:0)

在你的MyHistory类中你正在使用整数,所以在你的encodeWithCoder函数中你应该使用

coder.encodeInteger(self.kicksNumber, forKey: "kicksNumber")
coder.encodeInteger(self.durationNumber, forKey: "durationNumber") 

同样对于你的解码器你应该使用decodeIntForKey,而不是decodeObjectForKey。

kicksNumber = decoder.decodeIntegerForKey("kicksNumber")
durationNumber = decoder.decodeIntegerForKey("durationNumber")