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

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

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

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Xcode

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

Swift

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

Q&A

解決済

1回答

1158閲覧

SwiftUI/CoreData: initの引数にEntityをもつViewのPreviewを表示させる方法。

SwiftBeginner

総合スコア9

Core Data

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2022/09/17 10:40

前提

ItemというEntityが、Attributesにindex: Int16とname: Stringを持つとします。
ParentViewにおいてItemsがそのFetchedResultsです。
Itemsの要素がChildViewのinitの引数となります。

Swift

1struct ParentView: View{ 2 @Environment(\.managedObjectContext) private var context 3 @FetchRequest( 4 sortDescriptors: [NSSortDescriptor(keyPath: \Item.index, ascending: true)], 5 animation: .default) 6 private var items: FetchedResults<Item> 7 @State var currentIndex: Int = 0 8 var body: some View{ 9 VStack{ 10 Button("+1"){ 11 currentIndex += 1 12 } 13 ChildView(items[currentIndex]) 14 } 15 } 16} 17 18struct ChildView: View{ 19 var item: Item 20 init(_ item: Item){ 21 self.item = item 22 } 23 var body: some View{ 24 //略 25 } 26} 27

実現したいこと

この場合、ChildViewのPreviewを表示させるにはどうすればよいでしょうか?

Swift

1struct ChildView_Previews: PreviewProvider { 2 static var previews: some View { 3 ChildView( ).environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) 4 } 5}

ChildView()の( )の中にItemである何かを入れなければプレビューが表示されないようです。
ChildView_Previews内でPreview用のItemを作ることができれば良いのだろうかと思っていますが、その方法が分かりません。
もしくはPersistenceに書き込む方法もあるのかもしれませんが、その場合どうすればよいか見当もつきません。

アドバイスよろしくお願いいたします。

ParentViewのプレビューで間接的にChildViewをプレビューすることはできますが、どうにかChildViewのプレビューを直接したいと考えています。
何卒よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

新しいプロジェクトを作成する際にUse CoreDataを選択すると
Persistenceというファイルに
PersistenceControllerというstructが実装されていると思います。
プレビューのために?10件分のテストデータがメモリ上に作成されるように実装されているみたいです。
ContentView_Previewsもこれを使っているみたいです。

ChildView_Previewsもこれを使うと良いのかもしれません。
CoreDataは勉強中なので、、
最適な実装ではないかもしれませんが次のような感じはいかがでしょうか。

swift

1// ChildView 2struct ChildView_Previews: PreviewProvider { 3 static var previews: some View { 4 ChildView(item) 5 } 6 static var item: Item { 7 let context = PersistenceController.preview.container.viewContext 8 let request = Item.fetchRequest() 9 request.sortDescriptors = [NSSortDescriptor(keyPath: \Item.index, ascending: true)] 10 do { 11 let fetchedItems = try context.fetch(request) 12 return fetchedItems.first! 13 } catch { 14 fatalError() 15 } 16 } 17}

Persistenceファイルも一応記載しておきます。
初期のItemのEntityはtimestampのAttributeを設定するようになっていましたので、
indexとnameを設定するように修正してあります。

swift

1// Persistence 2import CoreData 3 4struct PersistenceController { 5 static let shared = PersistenceController() 6 7 static var preview: PersistenceController = { 8 let result = PersistenceController(inMemory: true) 9 let viewContext = result.container.viewContext 10 for i in 0..<10 { 11 let newItem = Item(context: viewContext) 12 newItem.index = Int16(i) 13 newItem.name = "name\(i)" 14 } 15 do { 16 try viewContext.save() 17 } catch { 18 // Replace this implementation with code to handle the error appropriately. 19 // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 20 let nsError = error as NSError 21 fatalError("Unresolved error \(nsError), \(nsError.userInfo)") 22 } 23 return result 24 }() 25 26 let container: NSPersistentContainer 27 28 init(inMemory: Bool = false) { 29 container = NSPersistentContainer(name: "PreviewProduct") 30 if inMemory { 31 container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") 32 } 33 container.loadPersistentStores(completionHandler: { (storeDescription, error) in 34 if let error = error as NSError? { 35 // Replace this implementation with code to handle the error appropriately. 36 // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 37 38 /* 39 Typical reasons for an error here include: 40 * The parent directory does not exist, cannot be created, or disallows writing. 41 * The persistent store is not accessible, due to permissions or data protection when the device is locked. 42 * The device is out of space. 43 * The store could not be migrated to the current model version. 44 Check the error message to determine what the actual problem was. 45 */ 46 fatalError("Unresolved error \(error), \(error.userInfo)") 47 } 48 }) 49 container.viewContext.automaticallyMergesChangesFromParent = true 50 } 51}

投稿2022/09/17 12:35

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

SwiftBeginner

2022/09/18 02:27

ありがとうございます!無事にプレビュー表示することができました!persistenceも記載していただいたことで非常にスムーズに進みました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問