質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1582閲覧

CoreDataで重複して保存が実行されてしまう

Ka_ya_

総合スコア31

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/07/30 03:38

編集2020/07/31 01:53

質問失礼します。

日付ごとのデータを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}

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2020/07/30 06:21

>>正しい日付が入っているデータだけでなく、同時に中身が空のデータも保存されてしまいます。 これは現在起こっている症状(不具合)だと思いますが、 >>新しい日付のデータが作成される時だけ一緒に空データが作成されるのですが というのは何でしょうか?
Ka_ya_

2020/07/30 06:29

fuzzballさん、ご確認いただきありがとうございます。 >>新しい日付のデータが作成される時だけ一緒に空データが作成されるのですが この箇所に関しては、 CoreDataModel.selectOne(date: CountViewController.nowDateString) にて1件取得するコードとif文は正常に機能しており、 その内部のinsertもしくはsaveに問題があるのではという事をお伝えしたくて記載しました。 説明が下手で申し訳ありません。 お手数ですが、ご確認よろしくお願い致します。
fuzzball

2020/07/30 06:40 編集

前半の「空のデータ」と後半の「空データ」は意味が違いますか? 後半の「空データ」は、前半の「正しい日付が入っているデータ」のことですか?
Ka_ya_

2020/07/30 07:09

fuzzballさん、ご確認ありがとうございます。 記載がややこしく、大変申し訳ありません。 空データに関しては、どちらも同じ意味となっております。 質問内容を簡潔に記載し直しますと、日付のデータがない場合に ・dateに値が入っているData型 ・dateに値が入っていないData型 が保存されてしまう状態なのですが、 ・dateに値が入っているData型 だけを保存したいというのが実現したい事です。 たびたびお手数をおかけして、申し訳ありません。 よろしくお願い致します。
fuzzball

2020/07/30 07:35

データが2つ保存されている、というのはどうやって確認しましたか? 確認方法と併せて、ログまたはスクショを見せて下さい。
Ka_ya_

2020/07/30 15:13

fuzzballさん、ご確認ありがとうございます。 データを全件取得してテーブルビューに表示し、中身を確認しました。 日付の入っているデータが作成される前に1つ空レコードが作成されている状態です。 (スクリーンショットの20200730の上にある空レコードの日付がブランクなのは、 デフォルト値の設定を削除しただけで20200729の上にある空レコードと同様の現象です) たびたびお手数をおかけしますが、ご確認よろしくお願い致します。
fuzzball

2020/07/30 23:50 編集

実際には「空データ」ではないですね。こういうのは正しく伝えた方が良いです。 で、そのテーブル表示がバグってる可能性はないですかね? ちょっと以下のことを試してみて下さい。 「//もし今日の日付でデータが存在しなかったら」の次の行に、 print(CountViewController.nowDateString, CoreDataModel.selectOne(date: CountViewController.nowDateString).count) を追加して、どのように表示されるか教えてもらえますか?(データが追加されるときと、追加されないときの両方) 今のところ、質問のコードにおかしいところは無いと思っています。 他のデータベースを触ってるところは無いのでしょうか?
Ka_ya_

2020/07/31 01:55

fuzzballさん、ご確認ありがとうございます。 伝え方が至らずにお手数をおかけして、大変申し訳ありません。 printを試してみたところ、 ・データがない場合(当日初回起動時) 20200731 0 ・データがある場合(2回目以降) 20200731 1 上記の様に表示されており、 printのselectOneを全件取得するメソッドに変更してcountしたところ、 20200731 2 と表示されました。 (if文を使用せずに毎回データ生成するようにすると、  countが2ずつ増えて行く為、2件ずつ生成されていると思われます) データベースの保存操作をしているのは、質問に記載の箇所だけとなります。 AppDelegateに記載しているCoreData関連のコードと、 全件取得に使用しているメソッドを追記いたしました。 何度もご迷惑をおかけして申し訳ありません。 よろしくお願い致します。
fuzzball

2020/07/31 02:16 編集

解決方法は分かりました。 insertNewObject()は必要ないようです。 CoreDataのことをよく知らないので、なぜ不要なのかは分かりません。 (let newData = Data(context: self.context) の時点で追加されているということでしょうか) 知らないままに色々聞いてしまいましたが、(たぶん)解決したということでご勘弁を。 不要の理由などはご自身で調べてみて下さい。
Ka_ya_

2020/07/31 03:41

fuzzballさん、ご回答ありがとうございます。 insertをコメントアウトしたところ、 無事に一件だけ保存する事が出来ました! 何度もお手数をお掛けしてしまい申し訳ありません。 原因の調べ方や質問の記載方法なども、とても勉強になりました。 解決していただき、本当にありがとうございます^^
guest

回答1

0

自己解決

コメントにてご回答いただけたので、解決済みとさせていただきます。
ありがとうございました。

投稿2020/08/01 02:05

Ka_ya_

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問