質問失礼します。
日付ごとのデータをCoreDataに保存したいです。
当日のデータがない場合は新規作成をする様に記載したのですが、
正しい日付が入っているデータだけでなく、
同時に中身が空のデータも保存されてしまいます。
新しい日付のデータが作成される時だけ一緒に空データが作成されるのですが、
insert,save文の使用方法が間違っているのでしょうか。
どなたかご教授いただけますと嬉しいです。
よろしくお願い致します。
SWift
1class CountViewController: UIViewController { 2 3 ///現在の日付 4 var nowDate = Date() 5 static var nowDateString = String() 6 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 11 //日付のフォーマットを変更する 12 let formatter: DateFormatter = DateFormatter() 13 formatter.dateFormat = "yyyyMMdd" 14 ///日付をStringにする 15 CountViewController.nowDateString = formatter.string(from: nowDate) 16 17 //もし今日の日付でデータが存在しなかったら 18 if CoreDataModel.selectOne(date: CountViewController.nowDateString) == [] { 19 //今日のデータを作成して保存する 20 CoreDataModel.insertData(date: CountViewController.nowDateString) 21 CoreDataModel.save() 22 23 } 24}
Swift
1class CoreDataModel { 2 3 static var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 4 5 //データを挿入する 6 static func insertData(date: String) { 7 //Data型を作成して値を反映させる 8 let newData = Data(context: self.context) 9 newData.date = date 10 //インサートする 11 NSEntityDescription.insertNewObject(forEntityName: "Data", into: context) 12 } 13 14 //データを保存する 15 static func save() { 16 //コミットする 17 (UIApplication.shared.delegate as! AppDelegate).saveContext() 18 } 19 20 //データを一件取得 21 static func selectOne(date: String) -> [Data] { 22 23 var data = [Data]() 24 25 let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data") 26 //条件指定 27 request.predicate = NSPredicate(format: "date == %@", date) 28 29 do{ 30 data = try context.fetch(request) as! [Data] 31 32 return data 33 34 }catch{ 35 print("エラー") 36 } 37 return data 38 } 39 40 //データを全件取得する 41 static func selectAll() -> [Data] { 42 43 var data = [Data]() 44 45 let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data") 46 do{ 47 data = try context.fetch(request) as! [Data] 48 49 return data 50 }catch{ 51 print("エラー") 52 } 53 return data 54 } 55}
SWift
1class AppDelegate: UIResponder, UIApplicationDelegate { 2 3//CoreData関連部分のみ抜粋 4 lazy var persistentContainer: NSPersistentContainer = { 5 6 let container = NSPersistentContainer(name: "CoreDataTest") 7 container.loadPersistentStores(completionHandler: { (storeDescription, error) in 8 if let error = error as NSError? { 9 10 fatalError("Unresolved error (error), (error.userInfo)") 11 } 12 }) 13 return container 14 }() 15 16 func saveContext () { 17 let context = persistentContainer.viewContext 18 if context.hasChanges { 19 do { 20 try context.save() 21 } catch { 22 let nserror = error as NSError 23 fatalError("Unresolved error (nserror), (nserror.userInfo)") 24 } 25 } 26 } 27}
>>正しい日付が入っているデータだけでなく、同時に中身が空のデータも保存されてしまいます。
これは現在起こっている症状(不具合)だと思いますが、
>>新しい日付のデータが作成される時だけ一緒に空データが作成されるのですが
というのは何でしょうか?
fuzzballさん、ご確認いただきありがとうございます。
>>新しい日付のデータが作成される時だけ一緒に空データが作成されるのですが
この箇所に関しては、
CoreDataModel.selectOne(date: CountViewController.nowDateString)
にて1件取得するコードとif文は正常に機能しており、
その内部のinsertもしくはsaveに問題があるのではという事をお伝えしたくて記載しました。
説明が下手で申し訳ありません。
お手数ですが、ご確認よろしくお願い致します。
前半の「空のデータ」と後半の「空データ」は意味が違いますか?
後半の「空データ」は、前半の「正しい日付が入っているデータ」のことですか?
fuzzballさん、ご確認ありがとうございます。
記載がややこしく、大変申し訳ありません。
空データに関しては、どちらも同じ意味となっております。
質問内容を簡潔に記載し直しますと、日付のデータがない場合に
・dateに値が入っているData型
・dateに値が入っていないData型
が保存されてしまう状態なのですが、
・dateに値が入っているData型
だけを保存したいというのが実現したい事です。
たびたびお手数をおかけして、申し訳ありません。
よろしくお願い致します。
データが2つ保存されている、というのはどうやって確認しましたか?
確認方法と併せて、ログまたはスクショを見せて下さい。
fuzzballさん、ご確認ありがとうございます。
データを全件取得してテーブルビューに表示し、中身を確認しました。
日付の入っているデータが作成される前に1つ空レコードが作成されている状態です。
(スクリーンショットの20200730の上にある空レコードの日付がブランクなのは、
デフォルト値の設定を削除しただけで20200729の上にある空レコードと同様の現象です)
たびたびお手数をおかけしますが、ご確認よろしくお願い致します。
実際には「空データ」ではないですね。こういうのは正しく伝えた方が良いです。
で、そのテーブル表示がバグってる可能性はないですかね?
ちょっと以下のことを試してみて下さい。
「//もし今日の日付でデータが存在しなかったら」の次の行に、
print(CountViewController.nowDateString, CoreDataModel.selectOne(date: CountViewController.nowDateString).count)
を追加して、どのように表示されるか教えてもらえますか?(データが追加されるときと、追加されないときの両方)
今のところ、質問のコードにおかしいところは無いと思っています。
他のデータベースを触ってるところは無いのでしょうか?
fuzzballさん、ご確認ありがとうございます。
伝え方が至らずにお手数をおかけして、大変申し訳ありません。
printを試してみたところ、
・データがない場合(当日初回起動時)
20200731 0
・データがある場合(2回目以降)
20200731 1
上記の様に表示されており、
printのselectOneを全件取得するメソッドに変更してcountしたところ、
20200731 2
と表示されました。
(if文を使用せずに毎回データ生成するようにすると、
countが2ずつ増えて行く為、2件ずつ生成されていると思われます)
データベースの保存操作をしているのは、質問に記載の箇所だけとなります。
AppDelegateに記載しているCoreData関連のコードと、
全件取得に使用しているメソッドを追記いたしました。
何度もご迷惑をおかけして申し訳ありません。
よろしくお願い致します。
解決方法は分かりました。
insertNewObject()は必要ないようです。
CoreDataのことをよく知らないので、なぜ不要なのかは分かりません。
(let newData = Data(context: self.context) の時点で追加されているということでしょうか)
知らないままに色々聞いてしまいましたが、(たぶん)解決したということでご勘弁を。
不要の理由などはご自身で調べてみて下さい。
fuzzballさん、ご回答ありがとうございます。
insertをコメントアウトしたところ、
無事に一件だけ保存する事が出来ました!
何度もお手数をお掛けしてしまい申し訳ありません。
原因の調べ方や質問の記載方法なども、とても勉強になりました。
解決していただき、本当にありがとうございます^^
回答1件
あなたの回答
tips
プレビュー
