"[RiskEntry]"タイプの配列にNSUserDefaultsとともに保存されたデータがあります。NSUserDefaults - 2番目のView Controllerで配列が空です
Main_ViewController
を:私はここに保存し、読み込みと保存のプロセスは私のコードでどのように見えるか(私は関係のないと私はSwift3を使用していたコードを取り出して)何をあなたに説明しましょう
First:クラスMain_ViewControllerで、私はポップオーバーから転送されたテキストを取得し、NSUserDefaultsをriskEntryにキー "newTry"で保存します(これは一時的な名前です;-)) - > 'func riskText riskTextTransferred:String) 'を返します。
Plan_ViewController
第二:Plan_ViewController上の表を取得するセグエを使用して、テーブルがキー「newTry」(cell.riskTitle.text = savedTitles[indexPath.row].title as String
)とriskEntryに保存されたテキストで満たされています。これはこれまですべて正常に動作します。ユーザーがセル(consequences.text)のテキストフィールドに値を入力すると、値の結果はriskEntryのために更新されています
サード
CustomCellとPlan_ViewController。だから最初は配列には結果のための空文字列がありました。今、エントリはテキストで更新されました。
if let index = savedTitle.index(where: {$0.title.contains(identifier)}) {
savedTitle[index].consequences = consequencesTranferred
新しい文字列は、キー "newTry"で保存されます。これは期待どおりに機能します。
Main_ViewController
第四:今、私は戻ってMain_ViewControllerに行くにPlan_ViewControllerを解任。 viewWillAppear()でキー "newTry"でArrayをロードしようとすると、空になります。
私は間違っていますか? Main_ViewControllerのPlan_ViewControllerから更新されたデータを正常にロードするにはどうしたらいいですか?
Main_ViewController
class Main_ViewController: UIViewController, UIPopoverPresentationControllerDelegate, UIGestureRecognizerDelegate {
var riskItemDefaults = UserDefaults.standard
var riskEntry = [RiskEntry]()
override func viewWillAppear(_ animated: Bool) {
if let dataArrayTitle = riskItemDefaults.object(forKey: "newTry") as? [NSData] {
var savedTitle = dataArrayTitle.map { RiskEntry(data: $0)! }
riskItemDefaults.synchronize()
// CHECKPOINT: all arrays are printed empty...
print ("savedTitle: ")
print (savedTitle)
print ("dataArrayTitle: ")
print (dataArrayTitle)
} else {
print ("nothing")
}
}
// ---------------- delegate function that creates the array items -----------------
func riskText(riskTextTransferred: String) {
// CHECKPOINT: Array is saved correctly
riskEntry = [RiskEntry(title: riskTextTransferred, consequences: "")]
let encoded = riskEntry.map {$0.encode() }
riskItemDefaults.set(encoded, forKey: "newTry")
riskItemDefaults.synchronize()
}
}
Plan_ViewController
class Plan_VC: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomCellUpdaterDelegate {
@IBOutlet weak var tableView: UITableView!
var riskEntry = [RiskEntry]()
var riskItemDefaults = UserDefaults.standard
// ---------------- table settings -----------------
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// load saved data and count number of entries for numberOfSections
let dataArrayTitles = riskItemDefaults.object(forKey: "newTry") as! [NSData]
let savedTitles = dataArrayTitles.map { RiskEntry(data: $0)! }
return savedTitles.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView!.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CellCustomized
cell.delegate = self
// load saved data and insert title in cell label
let dataArrayTitles = riskItemDefaults.object(forKey: "newTry") as! [NSData]
let savedTitles = dataArrayTitles.map { RiskEntry(data: $0)! }
cell.riskTitle.text = savedTitles[indexPath.row].title as String
return cell
}
// ---------------- delegate function from CustomCell -----------------
func transferData(consequencesTranferred: String, identifier: String) {
/// load entry
let dataArrayTitle = riskItemDefaults.object(forKey: "newTry") as! [NSData]
var savedTitle = dataArrayTitle.map { RiskEntry(data: $0)! }
riskItemDefaults.synchronize()
// CHECKPOINT: The entry is loaded correctly
print("loaded: ")
print(savedTitle)
/// filter entry for title contains identifier and update the empty string for consequences
if let index = savedTitle.index(where: {$0.title.contains(identifier)}) {
savedTitle[index].consequences = consequencesTranferred
let encoded = riskEntry.map { $0.encode() }
riskItemDefaults.set(encoded, forKey: "newTry")
riskItemDefaults.synchronize()
// CHECKPOINT: The entry is updated correctly
print("After updating for consequences: ")
print(savedTitle)
}else {
print ("No title with value identifier to be filtered")
}
}
}
CustomCell
// ----------- delegate to transfer entered data to VC ------------
protocol CustomCellUpdaterDelegate {
func transferData(consequencesTranferred: String, identifier: String)
}
// ---------------- start of calss CellCustomized -----------------
class CustomCell: UITableViewCell, UIPickerViewDataSource, UIPickerViewDelegate, UITextViewDelegate {
var myColorsClass = myColors()
var myStylesClass = myStyles()
var delegate: CustomCellUpdaterDelegate?
// text fields, text views and picker views
@IBOutlet weak var riskTitle: UITextView!
@IBOutlet weak var consequences: UITextView!
var nameIdentifier = String()
var textConsequences = String()
override func awakeFromNib() {
super.awakeFromNib()
// initiate textView delegate
consequences.delegate = self
} // nib end
// ---------------- listener for text view to save input in string when editing is finished -----------------
func textViewDidEndEditing(_ textView: UITextView) {
textConsequences = consequences.text
nameIdentifier = riskTitle.text
delegate?.transferData(consequencesTranferred: self.textConsequences, identifier: nameIdentifier)
}
}
基本的にNSUserDefaultsは、一時的なデータ、特にView Controller間で渡されるデータを保存する場所が間違っています。 – vadian
私のデータは一時的に保存されることは想定されていません。アプリケーションを再起動してもデータは使用可能になるはずです... – Jake2Finn
質問に誤解を招くかもしれませんが、Plan_VCからMain_VCにデータを渡して、このデータを保存したいのですが、それは正しいですか?その場合、NSUserDefaultsにデータを保存するための時間遅延があるため、デリゲートを使用する必要があります。 –