質問をご覧いただき、有難うございます。
現在、スケジュールアプリを作成しております。
実現したいこと:
ユーザーが指定した「タイトル(String)」「開始時刻(Date)」「終了時刻(Date)」を構造体として配列に追加し、UserDafaultsで保存したいと思っております。
保存したものを画面遷移後に取得し、TableViewCellに表示させたいと思っております。
調べたところ、構造体はUserdefaultsに保存ができないとのことでしたので、
下記URLを見ながら、「NSCodingとNSKeyedArchiverを使わないパターン」を試してみましたが、シミュレータを起動すると、デバックエリアに
Could not cast value of type '__NSCFData' (0x1094ea6d0) to 'NSArray' (0x1094eae28). (lldb)
と表示され、クラッシュしてしまいます。
URL:http://qiita.com/paming/items/a93b8572f65275eb1dd4
extensionやstructなど、使い慣れておりませんので、
使用時のルールや記載場所などで、間違いがあるかもしれません。
また、extensionで機能を拡張した後のUserdefaultsの使用方法などもご教示いただければ幸いです。
/* 表示データ */ struct ScheduleData{ // スケジュールのコメント var title: String = "" // スケジュールの開始時間 var startDate: Date! // スケジュールの終了時間 var endDate: Date! init(title : String , startDate : Date , endDate : Date){ self.title = title self.startDate = startDate self.endDate = endDate } } var schedules = [ScheduleData]()
func saveData() { dataOut() var dateFromString = myDateFormatter.date(from: dateTextField.text!) var dateFromString2 = myDateFormatter.date(from: dateTextField2.text!) if dateFromString != nil { if dateFromString2 != nil { if titleTextField.text! != nil { schedules.append(ScheduleData(title : titleTextField.text!, startDate : dateFromString!, endDate : dateFromString2!)) detailArray.append(detailTextView.text!) placeArray.append(placeTextField.text!) urlArray.append(urlTextField.text!) alarmDateArray.append(alarmTimeTextField.text!) UserDefaults.standard.set(schedules, forKey: "schedules") UserDefaults.standard.set(detailArray, forKey: "detailArray") UserDefaults.standard.set(placeArray, forKey: "placeArray") UserDefaults.standard.set(urlArray, forKey: "urlArray") UserDefaults.standard.set(alarmDateArray, forKey: "alarmDateArray") } } } else { warningAlertController() }
func dataOut() { if UserDefaults.standard.object(forKey: "schedules") != nil { schedules = UserDefaults.standard.object(forKey: "schedules") as! [ScheduleData] } if UserDefaults.standard.object(forKey: "detailArray") != nil { detailArray = UserDefaults.standard.object(forKey: "detailArray") as! [String] } if UserDefaults.standard.object(forKey: "placeArray") != nil { placeArray = UserDefaults.standard.object(forKey: "placeArray") as! [String] } if UserDefaults.standard.object(forKey: "urlArray") != nil { urlArray = UserDefaults.standard.object(forKey: "urlArray") as! [String] } if UserDefaults.standard.object(forKey: "alarmDateArray") != nil { alarmDateArray = UserDefaults.standard.object(forKey: "alarmDateArray") as! [String] } }
extension UserDefaults { var logDataArray:[ScheduleData]{ set(datas){ // Swiftのオブジェクトを、NSObjectなオブジェクトに変換する let newDatas:[NSDictionary] = datas.map{ ["title":$0.title, "startdate":$0.startDate, "endDate":$0.endDate] as NSDictionary } // NSObjectなオブジェクトのみになったから、setObjectできる self.set(newDatas,forKey:"schedules") } get{ // NSDictionaryの配列として、データを取得 let datas = self.object(forKey: "schedules") as? [NSDictionary] ?? [] // 保存されたデータから復元出来無い場合もあり得るので、 // mapではなくreduceを使う let array = datas.reduce([]){ (ary, d:NSDictionary) -> [ScheduleData] in // dateやmessageがnilでないなら、MyLogDataを作って足し込む if let title = d["title"] as? String, let endDate = d["endDate"] as? Date, let startDate = d["startDate"] as? Date { return ary + [ScheduleData(title: title, startDate: startDate, endDate: endDate)] }else{ return ary } } return array } } }
訂正箇所など、ご教示いただければ幸いです。
回答1件
あなたの回答
tips
プレビュー