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

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

新規登録して質問してみよう
ただいま回答率
86.12%
Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

iOS

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

Xcode

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

解決済

[SwiftUI]カスタムクラスへデータを保存したいです。

kngtkhr
kngtkhr

総合スコア8

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

iOS

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

Xcode

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

1回答

0リアクション

0クリップ

312閲覧

投稿2022/09/30 02:39

編集2022/09/30 02:50

前提

SwiftUIで以下のような明細欄を作っています。

商品列2列3
鉛筆AB
消しゴムCD
りんごEF
ノートGH

商品,列2,列3以外はTextFieldです。

こちらの記事を参考に、
明細欄の商品列のデータ(鉛筆, ...ノート)を保存したいのですが、保存できませんでした。

CoreData

ENTITIES : DetailTable
Attributes : detailList(Binary Data)

カスタムクラス

Detail.swift

import Foundation // Detail(明細)クラス定義 class Detail: NSObject, NSCoding { var ID = UUID() var productName = "" init(productName: String?) { self.productName = productName! } func encode(with aCoder: NSCoder) { aCoder.encode(self.productName, forKey: "productName") } required init?(coder aDecoder: NSCoder) { self.productName = aDecoder.decodeObject(forKey: "productName") as! String } }

データの保存

CreateView.swift

struct CreateView: View { @Environment(\.managedObjectContext) private var viewContext @State var detailField = ["", ""] ... var body: some View { ... } // 保存ボタン押下時の処理 private func createEstimate() { let detail = DetailTable(context: viewContext) // 明細情報の保存 let detailFields = detailField // 配列[鉛筆, 消しゴム, りんご, ノート] @State var detailList = [] for i in 0..<detailFields.count { let detail = Detail(productName: detailFields[i]) detailList.append(detail) } do { let detailListData: Data = try NSKeyedArchiver.archivedData(withRootObject: detailList, requiringSecureCoding: false) as Data detail.detailList = detailListData } catch let error { print(error.localizedDescription) } // 生成したインスタンスをCoreDataに保存する do { try viewContext.save() print("保存成功") } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } presentation.wrappedValue.dismiss() } }

実現したいこと

・カスタムクラスへデータを保存したいです。

発生している問題・エラーメッセージ

エラーメッセージはありません。

該当のソースコード

CreateView.swift

// 保存ボタン押下時の処理 private func createEstimate() { let detail = DetailTable(context: viewContext) // 明細情報の保存 let detailFields = detailField // 配列[鉛筆, 消しゴム, りんご, ノート] @State var detailList = [] for i in 0..<detailFields.count { let detail = Detail(productName: detailFields[i]) detailList.append(detail) }

試したこと

print()を使い、値が出力されているか試しました。

  1. 配列detailListには値が追加されていませんでした。
  2. 配列detailFieldsには値が追加されていました。
  3. detailにも値は入っていました。しかし、以下のような同じ値でした。

detail結果
<ProjectName.Detail: 0x600000ec46f0>
<ProjectName.Detail: 0x600000e63210>
<ProjectName.Detail: 0x600000e63210>
<ProjectName.Detail: 0x600000e63210>

補足情報(FW/ツールのバージョンなど)

macOS Monterey バージョン 12.3
Swift version 5.6.1
Xcode バージョン 13.4.1

たくさん調べたのですが解決できませんでした。
お力添えいただけますととても嬉しく思います。
よろしくお願いいたします。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

xg63ex2b

2022/09/30 13:49

Core Dataは レコード(行?)ごとに保存するのが一般的なのかな?と思うのですが、 (質問欄の例で言うと「鉛筆」「消しゴム」「りんご」「ノート」の4レコード) 1行にすべてのデータを保存しようとしているように見えます。 これには何か理由があるのでしょうか? *Core Dataを使用する意味があまりないように見えまして、普通のファイルでも良いのかな?と思いましたので確認してみました
kngtkhr

2022/09/30 21:13

コメントくださり、ありがとうございます。 私がリレーションシップを使ったCore Dataへの保存と呼び出しをできなかったのが理由になります。 特に ①概要テーブル:明細欄テーブルは1:多のリレーションシップがある時、概要テーブルが主キーになると、Viewから呼び出しずらくならないか ②保存した後、編集画面でCore Dataを呼び出すとき、2つのENTITIYの全てのカラムを呼び出すことができるか 1ヶ月間もがいているうちに、1レコード(行)に全てのデータを保存する方法なら明細欄の保存と呼び出しができると思い、このようなやり方になりました。 Core DataはiCloudと連携できる点が魅力と思い、採用しました。 もし私が質問したような1レコード(行)に全てのデータを保存する方法を使わない場合、 データベースを普通のファイルやRealm,Firebase等に変更する方がいいのか、 リレーションシップを使う方法が適しているのか、 アドバイス頂けると幸いです(T T) よろしくお願い致します。
xg63ex2b

2022/09/30 23:46

コメントありがとうございます。 そういう理由だったのですね。 1ヶ月進まないのはちょっと苦痛ですね・・ iCloudとの連携を考えるのでしたら、 Realm、FirebaseなどよりCore Dataの方が良いのかもしれませんね。 リレーションシップを使う方法が良い気がしますが、 具体的な問題点を正しく認識できていないかもしれませんので、 まだなんとも言えないです・・ --- 「リレーションシップを使ったCore Dataへの保存と呼び出しをできなかった」 というのは、Fetchで特定のレコードを取得できないということでしょうか? Filtering Results https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/FetchingObjects.html#//apple_ref/doc/uid/TP40001075-CH6-SW3 Fetch request https://developer.apple.com/library/archive/documentation/DataManagement/Devpedia-CoreData/fetchRequest.html#//apple_ref/doc/uid/TP40010398-CH26-SW1
kngtkhr

2022/10/01 00:44

ご返信ありがとうございます。 苦痛です・・・ リレーションシップを使う方法で進め、諦めず、形作っていこうと思います。 Fetchで概要テーブルの特定のレコードは取得できますが、リレーションシップを使って明細欄テーブルを呼び出すことができませんでした。 保存の方でも、概要テーブルの保存はできますが、明細欄テーブルに保存することができませんでした(TT) 新規作成するCreateView.swiftで保存ボタンを押し、Core Dataに保存する処理を行う部分において、リレーションシップの使い方が分からないままになっています。 // 保存ボタン押下時の処理 private func createEstimate() { let outline = OutlineTbl(context: viewContext) let detail = DetailTbl(context: viewContext) // ←viewContextの2個目を呼び出して概要テーブルと明細テーブルそれぞれに保存できるのか? outline.Number = Number outline.prjName = prjName outline.Date = createDate outline.updateDate = Date() detail.productName = productName // 生成したインスタンスをCoreDataに保存する try? viewContext.save() presentation.wrappedValue.dismiss() } リンクありがとうございます。 初めて見るリンクで参考になります。今から読みます。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Core Data

Core DataはAppleのOS X and iOSのためのオブジェクトモデリングと持続性を持ったフレームワークです。Xcodeはエンティティー、属性そして関係性を特定するためのオブジェクトモデルの編集機能を提供します。

iOS

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

Xcode

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