<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SwiftUI Data and Storage - AppMakers.Dev</title>
	<atom:link href="https://appmakers.dev/category/swiftui/swiftui-data-and-storage/feed/" rel="self" type="application/rss+xml" />
	<link>https://appmakers.dev/category/swiftui/swiftui-data-and-storage/</link>
	<description>SwiftUI Tutorials, iOS App Development, SwiftUI, Swift</description>
	<lastBuildDate>Mon, 09 Jun 2025 21:23:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://appmakers.dev/wp-content/uploads/2024/10/cropped-AppMakersDev-32x32.jpg</url>
	<title>SwiftUI Data and Storage - AppMakers.Dev</title>
	<link>https://appmakers.dev/category/swiftui/swiftui-data-and-storage/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Learn how to work with Xcode Previews in SwiftData App</title>
		<link>https://appmakers.dev/learn-how-to-work-with-xcode-previews-in-swiftdata-app/</link>
		
		<dc:creator><![CDATA[AppMakers]]></dc:creator>
		<pubDate>Wed, 16 Oct 2024 11:30:05 +0000</pubDate>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[SwiftData]]></category>
		<category><![CDATA[SwiftUI]]></category>
		<category><![CDATA[SwiftUI Data and Storage]]></category>
		<category><![CDATA[SwiftUI State Management and Data Flow]]></category>
		<category><![CDATA[SwiftUI Tutorials]]></category>
		<guid isPermaLink="false">https://appmakers.dev/?p=1776</guid>

					<description><![CDATA[<p>Learn how to work with Xcode Previews in SwiftData App. SwiftData in combination with SwiftUI allows you to quickly prototype and develop apps by providing easy-to-use, in-memory storage for model data. In this tutorial, we’ll walk through how to create sample recipe data using ModelContainer and display that data in SwiftUI views with previews. Step&#8230;</p>
<p>The post <a href="https://appmakers.dev/learn-how-to-work-with-xcode-previews-in-swiftdata-app/">Learn how to work with Xcode Previews in SwiftData App</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>Learn how to work with Xcode Previews in SwiftData App</strong>. SwiftData in combination with SwiftUI allows you to quickly prototype and develop apps by providing easy-to-use, in-memory storage for model data. In this tutorial, we’ll walk through how to create sample recipe data using <code class="" data-line="">ModelContainer</code> and display that data in SwiftUI views with previews.</p>
<h3>Step 1: Defining the <code class="" data-line="">Recipe</code> Model</h3>
<p>Setup a <code class="" data-line="">Recipe</code> model that represents a dish with a name, cooking time, and ingredients.</p>
<pre><code class="language-swift" data-line="">import Foundation
import SwiftData

@Model
class Recipe {

    @Attribute(.unique) var id: UUID
    var name: String?
    var cookingTime: Int // in minutes
    var ingredients: [String]

    init(id: UUID = UUID(), name: String? = nil, cookingTime: Int, ingredients: [String]) {
        self.id = id
        self.name = name
        self.cookingTime = cookingTime
        self.ingredients = ingredients
    }
}
</code></pre>
<p>This model defines each recipe with a unique ID, name, cooking time, and a list of ingredients. With this setup, you can now store recipes in SwiftData and use them in your app.</p>
<h3>Step 2: Creating Sample Data for Previews</h3>
<p>Now, let’s generate sample data using <code class="" data-line="">ModelContainer</code>. You’ve written a method to insert sample recipes into a <code class="" data-line="">ModelContainer</code> for use in previews.</p>
<pre><code class="language-swift" data-line="">import Foundation
import SwiftData

let sampleRecipes = [
    Recipe(name: &quot;Spaghetti Bolognese&quot;, cookingTime: 45, ingredients: [&quot;Spaghetti&quot;, &quot;Minced Beef&quot;, &quot;Tomato Sauce&quot;]),
    Recipe(name: &quot;Grilled Cheese Sandwich&quot;, cookingTime: 10, ingredients: [&quot;Bread&quot;, &quot;Cheese&quot;, &quot;Butter&quot;]),
    Recipe(name: &quot;Beef Wellington&quot;, cookingTime: 120, ingredients: [&quot;Beef Tenderloin&quot;, &quot;Puff Pastry&quot;, &quot;Mushrooms&quot;, &quot;Dijon Mustard&quot;])
]

extension Recipe {
    @MainActor static func makeSampleRecipes(in container: ModelContainer) {
        
        let context = container.mainContext
        
        // Check if there are any existing recipes in the database
           let existingRecipesCount = (try? context.fetch(FetchDescriptor()))?.count ?? 0
           guard existingRecipesCount == 0 else {
               // If there are existing recipes, do not create new ones
               return
           }
           
           // Sample data to create
           let recipes = [
               Recipe(name: &quot;Spaghetti Bolognese&quot;, cookingTime: 45, ingredients: [&quot;Spaghetti&quot;, &quot;Minced Beef&quot;, &quot;Tomato Sauce&quot;]),
               Recipe(name: &quot;Grilled Cheese Sandwich&quot;, cookingTime: 10, ingredients: [&quot;Bread&quot;, &quot;Cheese&quot;, &quot;Butter&quot;]),
               Recipe(name: &quot;Beef Wellington&quot;, cookingTime: 120, ingredients: [&quot;Beef Tenderloin&quot;, &quot;Puff Pastry&quot;, &quot;Mushrooms&quot;, &quot;Dijon Mustard&quot;])
           ]
           
           // Insert the sample recipes into the context
           for recipe in recipes {
               context.insert(recipe)
           }
           
           // Save the context to persist the new data
           try? context.save()
        
    }
}

</code></pre>
<p>This method defines three recipes and inserts them into the <code class="" data-line="">ModelContainer</code>. The <code class="" data-line="">@MainActor</code> annotation ensures this method runs on the main thread, which is essential for interacting with SwiftData.</p>
<h3>Step 3: Implementing the <code class="" data-line="">RecipeSampleData</code> for Previews</h3>
<p><span id="more-1776"></span><br />
The <code class="" data-line="">RecipeSampleData</code> structure serves as a <code class="" data-line="">PreviewModifier</code> to create in-memory sample data. This makes it easy to display recipes in SwiftUI previews.</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct RecipeSampleData: PreviewModifier {
    static func makeSharedContext() throws -&gt; ModelContainer {
        let config = ModelConfiguration(isStoredInMemoryOnly: true)
        let container = try ModelContainer(for: Recipe.self, configurations: config)
        Recipe.makeSampleRecipes(in: container) // Load sample recipes
        return container
    }
    
    func body(content: Content, context: ModelContainer) -&gt; some View {
        content.modelContainer(context)
    }
}

extension PreviewTrait where T == Preview.ViewTraits {
    @MainActor static var sampleRecipeData: Self = .modifier(RecipeSampleData())
}
</code></pre>
<p>This modifier creates a <code class="" data-line="">ModelContainer</code> configured for in-memory storage. The <code class="" data-line="">makeSampleRecipes</code> method loads sample recipes into the container, and the modifier applies this data to any view using the <code class="" data-line="">.modelContainer()</code> modifier.</p>
<h3>Step 4: Creating Recipe Views with Sample Data</h3>
<p>Now let’s integrate this sample data into a few SwiftUI views.</p>
<h4>Recipe List View</h4>
<p>The <code class="" data-line="">RecipeListView</code> displays a list of recipes loaded from SwiftData. The <code class="" data-line="">@Query</code> property wrapper retrieves the recipes, and the list is built dynamically.</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct RecipeListView: View {
    @Query private var recipies: [Recipe]
    @Environment(\.modelContext) private var context
    
    var body: some View {
       
        List {
            ForEach(recipies) { recipe in
              
                VStack(alignment: .leading) {
                    Text(recipe.name ?? &quot;&quot;)
                           .font(.headline)
                       Text(&quot;Cooking Time: \(recipe.cookingTime) mins&quot;)
                           .font(.subheadline)
                   }
            }
        } .task {
            
               Recipe.makeSampleRecipes(in: context.container)
        }
    }
}

#Preview(traits: .sampleRecipeData) {
    RecipeListView()
}
</code></pre>
<p>In this example, the <code class="" data-line="">@Query</code> property wrapper retrieves all <code class="" data-line="">Recipe</code> objects from the <code class="" data-line="">ModelContainer</code>, which are then displayed in a <code class="" data-line="">List</code> using SwiftUI. The preview uses <code class="" data-line="">.sampleRecipeData</code> to load in-memory recipes for testing the UI.</p>
<h4>Recipe Detail View</h4>
<p>For more detailed recipe information, the <code class="" data-line="">RecipeDetailView</code> displays the name, cooking time, and ingredients of a single recipe. This view doesn’t query for data but accepts a <code class="" data-line="">Recipe</code> object as a parameter.</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct RecipeDetailView: View {
    let recipe: Recipe

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(recipe.name ?? &quot;No Name&quot;)
                .font(.largeTitle)
            Text(&quot;Cooking Time: \(recipe.cookingTime) mins&quot;)
                .padding(.bottom)
            Text(&quot;Ingredients:&quot;)
            ForEach(recipe.ingredients, id: \.self) { ingredient in
                Text(ingredient)
            }
        }
        .padding()
    }
}

#Preview(traits: .sampleRecipeData) {
    @Previewable @Query var recipes: [Recipe]  // Query sample recipes
    RecipeDetailView(recipe: recipes.first!)
}
</code></pre>
<p>In this view, the recipe&#8217;s details are displayed, including the name, cooking time, and ingredients. The preview fetches the first recipe from the sample data.</p>
<h3>Step 5</h3>
<p>Now let&#8217;s connect our ListView with a DetailView using a NavigationLink inside a NavigationStack</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct RecipeListView: View {
    @Query private var recipies: [Recipe]
    @Environment(\.modelContext) private var context
    
    var body: some View {
       
        NavigationStack {
            List {
                ForEach(recipies) { recipe in
                    NavigationLink(destination: RecipeDetailView(recipe: recipe)) {
                        
                        // Recipe Row
                        VStack(alignment: .leading) {
                            Text(recipe.name ?? &quot;&quot;)
                                .font(.headline)
                            Text(&quot;Cooking Time: \(recipe.cookingTime) mins&quot;)
                                .font(.subheadline)
                        }
                    }
                }
            } .task {
                
                Recipe.makeSampleRecipes(in: context.container)
                
            }
        }
    }
}

#Preview(traits: .sampleRecipeData) {
    RecipeListView()
}</code></pre>
<h3>Key Differences Between <code class="" data-line="">Preview</code> and <code class="" data-line="">@Previewable</code></h3>
<ol>
<li><strong><code class="" data-line="">Preview</code> with Traits (<code class="" data-line="">.sampleRecipeData</code>)</strong>:
<ul>
<li>Best for views that query data using SwiftData.</li>
<li>Automatically loads sample data into the view’s query and binds it to the UI.</li>
<li>No need to manually pass data; the query handles it for you.</li>
</ul>
</li>
<li><strong><code class="" data-line="">@Previewable</code></strong>:
<ul>
<li>Best for views that rely on models passed in as parameters (e.g., detail views).</li>
<li>Allows you to create sample data and pass it directly to the view.</li>
<li>You have full control over what specific data is provided for the preview.</li>
</ul>
</li>
</ol>
<h3>Conclusion</h3>
<p>By using <code class="" data-line="">SampleData</code> and the <code class="" data-line="">@Previewable</code> macro, you can easily preview recipe data within your SwiftUI views. Whether you’re working with data that relies on queries or views that require individual models, SwiftData provides an efficient way to prototype and test your app in Xcode.</p>
<p>The post <a href="https://appmakers.dev/learn-how-to-work-with-xcode-previews-in-swiftdata-app/">Learn how to work with Xcode Previews in SwiftData App</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to display sample SwiftData in SwiftUI with PreviewModifier</title>
		<link>https://appmakers.dev/how-to-display-sample-swiftdata-in-swiftui-with-previewmodifier/</link>
		
		<dc:creator><![CDATA[AppMakers]]></dc:creator>
		<pubDate>Sun, 13 Oct 2024 20:28:51 +0000</pubDate>
				<category><![CDATA[SwiftData]]></category>
		<category><![CDATA[SwiftUI]]></category>
		<category><![CDATA[SwiftUI Data and Storage]]></category>
		<category><![CDATA[SwiftUI Tutorials]]></category>
		<guid isPermaLink="false">https://appmakers.dev/?p=1765</guid>

					<description><![CDATA[<p>In this tutorial, we will explore how to display sample SwiftData in SwiftUI with PreviewModifier Step 1: Define the Entity First, we need to define a Task entity that we will use to store our task data in SwiftData. import Foundation import SwiftData @Model class Task { @Attribute(.unique) var id: UUID var title: String? var isCompleted:&#8230;</p>
<p>The post <a href="https://appmakers.dev/how-to-display-sample-swiftdata-in-swiftui-with-previewmodifier/">How to display sample SwiftData in SwiftUI with PreviewModifier</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this tutorial, we will explore how to display sample SwiftData in SwiftUI with PreviewModifier</p>
<h2>Step 1: Define the Entity</h2>
<p>First, we need to define a <code class="" data-line="">Task</code> entity that we will use to store our task data in SwiftData.</p>
<pre><code class="language-swift" data-line="">import Foundation
import SwiftData

@Model
class Task {
    @Attribute(.unique) var id: UUID
    var title: String?
    var isCompleted: Bool

    init(id: UUID = UUID(), title: String? = nil, isCompleted: Bool = false) {
        self.id = id
        self.title = title
        self.isCompleted = isCompleted
    }
}
</code></pre>
<p>In this code, we define the <code class="" data-line="">Task</code> model with an <code class="" data-line="">id</code>, <code class="" data-line="">title</code>, and <code class="" data-line="">isCompleted</code> property. The <code class="" data-line="">@Model</code> attribute is used to make this class a SwiftData model.</p>
<h2>Step 2: Create the Task List View</h2>
<p>Next, we&#8217;ll create a SwiftUI view that displays a list of tasks, each with a toggle for marking them as completed or not.</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct TaskListView: View {
    @Query(sort: \Task.title) private var tasks: [Task]
    @Environment(\.modelContext) private var context
    
    var body: some View {
        List {
            ForEach(tasks) { task in
                HStack {
                    Text(task.title ?? &quot;&quot;)
                        .font(.title2)
                        .foregroundColor(task.isCompleted ? .green : .black)
                    
                    Spacer()
                    
                    Toggle(&quot;&quot;, isOn: Bindable(task).isCompleted)
                   
                }
            }
            .onDelete(perform: deleteTask)
        }
        .task {
            
            for task in sampleTasks {
                context.insert(task)
            }
            
        }
        .navigationTitle(&quot;Tasks&quot;)
    }
    
    private func updateTaskCompletion(_ task: Task, newValue: Bool) {
        task.isCompleted = newValue
        try? context.save()
    }
    
    private func deleteTask(at offsets: IndexSet) {
        for index in offsets {
            context.delete(tasks[index])
        }
        try? context.save()
    }
}
</code></pre>
<p>In this view, each task can be marked as completed by toggling a switch, and we handle saving this state with <strong>SwiftData</strong>.</p>
<h2>Step 3: Preview with SwiftData Context</h2>
<p>To make the preview functional, we need to set up a SwiftData context. We’ll use the <code class="" data-line="">PreviewModifier</code> protocol to create a shared context that holds some sample data.<span id="more-1765"></span></p>
<pre><code class="language-swift" data-line="">import Foundation
import SwiftUI
import SwiftData

let sampleTasks = [
    Task(title: &quot;Buy Groceries&quot;),
    Task(title: &quot;Walk the Dog&quot;, isCompleted: true),
    Task(title: &quot;Complete SwiftUI Project&quot;)
]

struct SampleTaskData: PreviewModifier {
    static func makeSharedContext() throws -&gt; ModelContainer {
        let container = try ModelContainer(for: Task.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))

        for task in sampleTasks {
            container.mainContext.insert(task)
        }
        
        return container
    }

    func body(content: Content, context: ModelContainer) -&gt; some View {
        content.modelContainer(context)
    }
}

extension PreviewTrait where T == Preview.ViewTraits {
    static var sampleTaskData: Self = .modifier(SampleTaskData())
}
</code></pre>
<p>In this example, the <code class="" data-line="">SampleTaskData</code> struct conforms to <code class="" data-line="">PreviewModifier</code>, providing a shared SwiftData context with in-memory tasks for the preview.</p>
<h2>Step 4: Add a Preview #Preview(traits:</h2>
<p>Now, let&#8217;s create a dynamic preview</p>
<pre><code class="language-swift" data-line="">#Preview(traits: .sampleTaskData) {
    TaskListView()
}</code></pre>
<h2>Step 5. Add <code class="" data-line="">@Previewable</code> to Preview</h2>
<p>Now, we&#8217;ll use the <code class="" data-line="">@Previewable</code> attribute inside the <code class="" data-line="">#Preview</code> macro to interact with the <code class="" data-line="">Task</code> completion status dynamically.</p>
<pre><code class="language-swift" data-line="">#Preview(&quot;Dynamic Task Preview&quot;) {
    @Previewable @State var isTaskCompleted = false
    let sampleTask = Task(title: &quot;Complete SwiftUI Project&quot;, isCompleted: isTaskCompleted)
    
    return HStack {
        Text(sampleTask.title ?? &quot;&quot;)
            .font(.title2)
            .foregroundColor(sampleTask.isCompleted ? .green : .black)
        
        Spacer()
        
        Toggle(&quot;&quot;, isOn: $isTaskCompleted)
    }
}</code></pre>
<p>In this preview:</p>
<ul>
<li>The <code class="" data-line="">@Previewable</code> attribute tags the <code class="" data-line="">isTaskCompleted</code> state variable.</li>
<li>This allows you to toggle the state of <code class="" data-line="">isTaskCompleted</code> directly in the Xcode preview and see real-time changes.</li>
<li>The task’s completion status will update dynamically as you interact with the toggle in the preview.</li>
</ul>
<p>This tutorial demonstrated how to display sample SwiftData in SwiftUI with PreviewModifier and @Previewable</p>
<p>The post <a href="https://appmakers.dev/how-to-display-sample-swiftdata-in-swiftui-with-previewmodifier/">How to display sample SwiftData in SwiftUI with PreviewModifier</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SwiftData Tutorial &#8211; How to Implement SwiftData in SwiftUI App</title>
		<link>https://appmakers.dev/swiftdata-tutorial/</link>
		
		<dc:creator><![CDATA[AppMakers]]></dc:creator>
		<pubDate>Sat, 12 Oct 2024 03:46:05 +0000</pubDate>
				<category><![CDATA[SwiftData]]></category>
		<category><![CDATA[SwiftUI]]></category>
		<category><![CDATA[SwiftUI Data and Storage]]></category>
		<category><![CDATA[SwiftUI Tutorials]]></category>
		<guid isPermaLink="false">https://uiexamples.com/?p=572</guid>

					<description><![CDATA[<p>SwiftData offers a seamless way to manage and persist data with minimal effort. In this article, we&#8217;ll explore how to implement a simple SwiftData model, set up persistent storage, and manipulate data within SwiftUI views. Let&#8217;s start our SwiftData Tutorial. What is SwiftData? SwiftData is a data management framework introduced by Apple, designed to integrate&#8230;</p>
<p>The post <a href="https://appmakers.dev/swiftdata-tutorial/">SwiftData Tutorial &#8211; How to Implement SwiftData in SwiftUI App</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>SwiftData offers a seamless way to manage and persist data with minimal effort. In this article, we&#8217;ll explore how to implement a simple SwiftData model, set up persistent storage, and manipulate data within SwiftUI views. Let&#8217;s start our SwiftData Tutorial.</p>
<h2>What is SwiftData?</h2>
<p>SwiftData is a data management framework introduced by Apple, designed to integrate seamlessly with Swift and SwiftUI. It provides a simple yet powerful way to manage and persist data in iOS and macOS apps without needing extensive setup. By leveraging the <code class="" data-line="">@Model</code> macro, developers can define Swift classes as persistent data models, allowing the framework to automatically handle database schemas, change tracking, and data synchronization. SwiftData also supports key features like iCloud syncing, in-memory storage for testing, and relationship management between models, making it an ideal tool for modern app development. Its deep integration with SwiftUI ensures that any changes to your data automatically trigger UI updates, simplifying the development process and enhancing the performance of data-driven apps.</p>
<h3>Step 1: Setting Up Your SwiftData Model</h3>
<p>First, let’s create a model representing something simple. In our case, we&#8217;ll model a <strong>Book</strong>. We&#8217;ll define properties such as the book&#8217;s title, author, and genre. You can add more attributes as needed.</p>
<h4>1.1 Create the Model File</h4>
<ul>
<li>Open Xcodea and. Create a new Swift file called <code class="" data-line="">Book.swift</code>.</li>
<li>Import <code class="" data-line="">SwiftData</code>.</li>
<li>Define your model class with the <code class="" data-line="">@Model</code> macro. This macro ensures that your class is recognized by SwiftData for persistence.</li>
</ul>
<pre><code class="language-swift" data-line="">import SwiftData

@Model
class Book {
    var title: String
    var author: String
    var genre: String?
    
    init(title: String, author: String, genre: String? = nil) {
        self.title = title
        self.author = author
        self.genre = genre
    }
}
</code></pre>
<p><strong>Note</strong>: Optionals are important in SwiftData because non-optional properties must always have a value. If you’re planning future migrations, use optionals (<code class="" data-line="">?</code>) for fields that could be nil.</p>
<h3>Step 2: Setting Up the Main App and Model Container</h3>
<p>Before we can persist and manipulate <code class="" data-line="">Book</code> instances, we need to configure the model container in our main app file.</p>
<h4>2.1 Set Up Model Container</h4>
<ol>
<li>In your main <code class="" data-line="">App</code> file, import <code class="" data-line="">SwiftData</code>.</li>
<li>Use the <code class="" data-line="">.modelContainer</code> modifier to declare the models that should be persisted across app launches.</li>
</ol>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

@main
struct BookApp: App {
    var body: some Scene {
        WindowGroup {
            MainView().modelContainer(for: [Book.self])
        }
    }
}
</code></pre>
<p>This setup creates a default model container that stores data persistently. If you need to use a different storage method (e.g., in-memory), you can customize it, but for this example, we&#8217;ll stick with the default.</p>
<h3>Step 3: Creating a View to Display and Modify Data</h3>
<p>Now that we have our <code class="" data-line="">Book</code> model and the model container set up, we can create a SwiftUI view to display and modify the data.</p>
<h4>3.1 Fetching Data Using <code class="" data-line="">@Query</code></h4>
<p><span id="more-572"></span></p>
<p>SwiftData simplifies fetching data with the <code class="" data-line="">@Query</code> property wrapper, allowing us to query models and automatically update the UI when data changes.</p>
<pre><code class="language-swift" data-line="">import SwiftUI
import SwiftData

struct MainView: View {
    @Query(sort: \Book.title, order: .forward) private var books: [Book]
    @Environment(\.modelContext) private var context
    
    @State private var newBookTitle = &quot;&quot;
    @State private var newBookAuthor = &quot;&quot;
    @State private var newBookGenre = &quot;&quot;
    
    var body: some View {
        NavigationStack {
            VStack {
                // List of books
                List(books) { book in
                    HStack {
                        Text(book.title)
                        Spacer()
                        Text(book.author)
                    }
                }
                
                // Form to add a new book
                VStack {
                    TextField(&quot;Title&quot;, text: $newBookTitle)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                    TextField(&quot;Author&quot;, text: $newBookAuthor)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                    TextField(&quot;Genre&quot;, text: $newBookGenre)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                    
                    Button(&quot;Add Book&quot;) {
                        addNewBook()
                    }
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
                }
            }
            .navigationTitle(&quot;Books&quot;)
        }
    }
    
    // Function to add a new book
    private func addNewBook() {
        let newBook = Book(title: newBookTitle, author: newBookAuthor, genre: newBookGenre.isEmpty ? nil : newBookGenre)
        context.insert(newBook)
        
        do {
            try context.save()
        } catch {
            print(&quot;Failed to save book: \(error.localizedDescription)&quot;)
        }
        
        // Reset form fields
        newBookTitle = &quot;&quot;
        newBookAuthor = &quot;&quot;
        newBookGenre = &quot;&quot;
    }
}
</code></pre>
<p>Here’s what’s happening:</p>
<ul>
<li><strong>Fetching Data</strong>: The <code class="" data-line="">@Query</code> property fetches all <code class="" data-line="">Book</code> instances, sorted by title.</li>
<li><strong>Environment Model Context</strong>: The <code class="" data-line="">@Environment(\.modelContext)</code> provides access to the current model context for saving or deleting data.</li>
<li><strong>Adding a New Book</strong>: The <code class="" data-line="">addNewBook</code> function inserts a new <code class="" data-line="">Book</code> into the context and saves the changes.</li>
</ul>
<h3>Step 4: Previewing and Working with In-Memory Storage</h3>
<p>For previews and testing, we can use an in-memory container. This prevents saving the data permanently and resets it between preview runs.</p>
<pre><code class="language-swift" data-line="">#Preview {
    MainView().modelContainer(for: [Book.self], inMemory: true)
}
</code></pre>
<p>Using in-memory storage is particularly useful when testing or running previews, as it ensures that each run starts with a clean state.</p>
<h3>Step 5: Deleting a Book</h3>
<p>You can enable deletion of items in the list by adding a swipe-to-delete action. Add this to the <code class="" data-line="">List</code> view:</p>
<pre><code class="language-swift" data-line="">List {
    ForEach(books) { book in
        HStack {
            Text(book.title)
            Spacer()
            Text(book.author)
        }
    }
    .onDelete(perform: deleteBook)
}
</code></pre>
<p>Then, define the <code class="" data-line="">deleteBook</code> function:</p>
<pre><code class="language-swift" data-line="">private func deleteBook(at offsets: IndexSet) {
    for index in offsets {
        context.delete(books[index])
    }
    
    do {
        try context.save()
    } catch {
        print(&quot;Failed to delete book: \(error.localizedDescription)&quot;)
    }
}
</code></pre>
<p>This function removes the selected <code class="" data-line="">Book</code> from the context and saves the change.</p>
<h2>Conclusion</h2>
<p>In this article, we&#8217;ve covered how to:</p>
<ul>
<li>Set up a simple model with SwiftData.</li>
<li>Create a model container to persist data.</li>
<li>Fetch and display data using <code class="" data-line="">@Query</code>.</li>
<li>Add, delete, and persist data within a SwiftUI view.</li>
</ul>
<p>SwiftData is powerful yet straightforward, making data management in SwiftUI apps easier and more efficient. You can further extend this example by adding relationships, more complex attributes, or custom storage configurations. Happy coding!</p>
<p>The post <a href="https://appmakers.dev/swiftdata-tutorial/">SwiftData Tutorial &#8211; How to Implement SwiftData in SwiftUI App</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>@AppStorage and @SceneStorage in SwiftUI</title>
		<link>https://appmakers.dev/appstorage-scenestorage-swiftui/</link>
		
		<dc:creator><![CDATA[AppMakers]]></dc:creator>
		<pubDate>Wed, 01 May 2024 15:53:23 +0000</pubDate>
				<category><![CDATA[Export Free]]></category>
		<category><![CDATA[SwiftUI]]></category>
		<category><![CDATA[SwiftUI Data and Storage]]></category>
		<category><![CDATA[SwiftUI Tutorials]]></category>
		<guid isPermaLink="false">https://uiexamples.com/?p=510</guid>

					<description><![CDATA[<p>In SwiftUI, managing the state of your application through restarts and multitasking environments is crucial for creating a seamless user experience. SwiftUI provides two powerful tools, @AppStorage and @SceneStorage, designed to help developers handle state preservation and restoration efficiently. This tutorial will explore how to use these tools to save and retrieve user interface state&#8230;</p>
<p>The post <a href="https://appmakers.dev/appstorage-scenestorage-swiftui/">@AppStorage and @SceneStorage in SwiftUI</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In SwiftUI, managing the state of your application through restarts and multitasking environments is crucial for creating a seamless user experience. SwiftUI provides two powerful tools, <code class="" data-line="">@AppStorage</code> and <code class="" data-line="">@SceneStorage</code>, designed to help developers handle state preservation and restoration efficiently. This tutorial will explore how to use these tools to save and retrieve user interface state across app launches and during active sessions.</p>
<h3>Using @AppStorage for Persistent State Management</h3>
<p><code class="" data-line="">@AppStorage</code> reads and writes values to <code class="" data-line="">UserDefaults</code>, automatically updating your view when values change. It is ideal for storing simple data types and user preferences that need to persist between app launches.</p>
<h4>Example: Storing User Preferences with @AppStorage</h4>
<pre><code class="language-swift" data-line="">import SwiftUI

struct SettingsView: View {
    @AppStorage(&quot;darkModeEnabled&quot;) private var darkModeEnabled: Bool = false

    var body: some View {
        Toggle(&quot;Enable Dark Mode&quot;, isOn: $darkModeEnabled)
            .padding()
    }
}
</code></pre>
<p><strong>What&#8217;s Happening:</strong></p>
<ul>
<li>The <code class="" data-line="">Toggle</code> control is bound to <code class="" data-line="">darkModeEnabled</code>, stored in <code class="" data-line="">UserDefaults</code> under the key <code class="" data-line="">&quot;darkModeEnabled&quot;</code>.</li>
<li>Changes to the toggle will automatically save to <code class="" data-line="">UserDefaults</code> and the view will update accordingly to reflect the user&#8217;s preference.</li>
</ul>
<h3>Using @SceneStorage for Scene-Specific State Restoration</h3>
<p><code class="" data-line="">@SceneStorage</code> is used to store data specific to a scene, which is useful for apps that support multiple windows or need to manage state in complex multi-scene setups like on iPadOS.</p>
<h4>Example: Preserving Text Editor State with @SceneStorage</h4>
<pre><code class="language-swift" data-line="">import SwiftUI

struct EditorView: View {
    @SceneStorage(&quot;editorContent&quot;) private var editorContent: String = &quot;&quot;

    var body: some View {
        NavigationStack {
            TextEditor(text: $editorContent)
                .padding()
        }
    }
}
</code></pre>
<p><strong>What&#8217;s Happening:</strong></p>
<ul>
<li><code class="" data-line="">TextEditor</code> is bound to <code class="" data-line="">editorContent</code>, which is stored and restored automatically for each scene instance using <code class="" data-line="">@SceneStorage</code>.</li>
<li>If the user edits text in one window, closes the app, and reopens it, the text they were editing will be preserved and restored.</li>
</ul>
<h3>Practical Considerations</h3>
<ul>
<li><strong>Data Security</strong>: Neither <code class="" data-line="">@AppStorage</code> nor <code class="" data-line="">@SceneStorage</code> should be used for storing sensitive data as they do not provide secure storage.</li>
<li><strong>Data Volume</strong>: It is recommended to only store minimal data necessary for restoring state. Large data sets should be managed differently, possibly using databases or more secure storage solutions.</li>
</ul>
<h3>Conclusion</h3>
<p>Using <code class="" data-line="">@AppStorage</code> and <code class="" data-line="">@SceneStorage</code> in SwiftUI enables developers to manage app state effectively, providing continuity for users across app launches and maintaining individual scene states in multi-window environments. By integrating these tools, you can enhance the robustness and user-friendliness of your SwiftUI applications. Experiment with these property wrappers to find the best ways to keep your app&#8217;s user interface responsive and intuitive.</p>
<p>The post <a href="https://appmakers.dev/appstorage-scenestorage-swiftui/">@AppStorage and @SceneStorage in SwiftUI</a> appeared first on <a href="https://appmakers.dev">AppMakers.Dev</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
