基本的に、アプリを閉じて再度開くたびに、履歴タブを開くとクラッシュします。NSUserDefaults の使い方のせいだと確信しています。誰でも私を案内できますか?
私が気づいたのは、再度開いた後に [履歴] タブが開くことがありますが、Nsuserdefaults に新しいエントリを追加するとクラッシュし、再度開いた後は正常に動作し、以前のエントリが表示されるか、すべてが削除されて新しいエントリが保持されることです。それだけ。
//
// SecondViewController.swift
// Angelina
//
// Created by Artiom Sobol on 1/3/16.
// Copyright © 2016 Artiom Sobol. All rights reserved.
//
import UIKit
class History: UIViewController, UITableViewDataSource, UITableViewDelegate
{
// test variable
var test: MyHistory!
// array to store unarchived history
var newHistory = [MyHistory]()
//outlet for tableview
let defaults = NSUserDefaults.standardUserDefaults()
@IBOutlet var tableView: UITableView!
override func viewDidLoad()
{
//change the background
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "newBackground.jpg")!)
super.viewDidLoad()
if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
}
tableView.delegate = self
tableView.dataSource = self
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int
{
return self.newHistory.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("historyCell", forIndexPath: indexPath) as! historyCell
let person = newHistory[indexPath.item]
// let defaults2 = NSUserDefaults.standardUserDefaults()
print("This is count", newHistory.count)
// if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
// newHistory = //NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
// }
// cell.durationLabel.text = String(person.durationNumber)
let (hour,minutes,seconds) = secondsToHoursMinutesSeconds(person.durationNumber)
if(seconds < 10 && minutes < 10)
{
cell.durationLabel.text = "0\(hour):0\(minutes):0\(seconds)"
}
else if(seconds > 9 && minutes < 10)
{
cell.durationLabel.text = "0\(hour):0\(minutes):\(seconds)"
}
else if(seconds > 9 && minutes > 9)
{
cell.durationLabel.text = "0\(hour):\(minutes):\(seconds)"
}
else if(seconds < 10 && minutes > 9)
{
cell.durationLabel.text = "0\(hour):\(minutes):0\(seconds)"
}
cell.kicksLabel.text = String(person.kicksNumber)
return cell
}
func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int)
{
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
}
アプリをオフにすると、アレイが再起動されることに気付きました。それが、範囲外になるため、テーブルがクラッシュする理由です..
これは、配列の保存が行われる私の他のファイルです。
import UIKit
class Kicks: UIViewController
{
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!
var dateString = " "
@IBOutlet var timerLabel: UITextField!
@IBOutlet var kicksLabel: UITextField!
@IBOutlet var dateDisplay: UITextField!
@IBOutlet var kickbutton: UIButton!
var myHistoryArray: [MyHistory] = []
var currentMyHistory: MyHistory!
override func viewDidLoad()
{
super.viewDidLoad()
self.printTimestamp()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background13.png")!)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func kickButton()
{
//currentMyHistory.kicksNumber = 5
kickbutton.setImage(UIImage(named: "gold-button-heart-icon.png"), forState: UIControlState.Normal)
if(pressedOnce == true)
{
pressedOnce = false
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counter"), userInfo: nil, repeats: true)
}
else if(kickReached == true)
{
// let date = NSDate()
// let calendar = NSCalendar.currentCalendar()
// let timer_total = calendar.components([ .Hour, .Minute, .Second], fromDate: date)
}
else if(pressedOnce == false)
{
countKicks++
kicksLabel.text = "\(countKicks)"
if(countKicks == 10)
{
self.printTimestamp()
kickReached = true
timer.invalidate()
kickbutton.setImage(UIImage(named: "pink-button-heart-icon.png"), forState: UIControlState.Normal)
congratsAlert()
currentMyHistory = MyHistory(kicksNumber: countKicks, durationNumber: count)
myHistoryArray.append(currentMyHistory)
test = myHistoryArray[0]
print("countof array ", myHistoryArray.count)
printTimestamp() // Prints "Sep 9, 2014, 4:30 AM"
//save data
let savedData = NSKeyedArchiver.archivedDataWithRootObject(myHistoryArray)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savedData, forKey: "MyHistory")
clear()
}
}
}
func printTimestamp() {
let timestamp = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .MediumStyle, timeStyle: .ShortStyle)
print(timestamp)
dateDisplay.text = "\(timestamp)"
}
// 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)
}
}