Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 3824
Alex Hales
  • 0
Alex HalesTeacher
Asked: June 3, 20222022-06-03T03:31:39+00:00 2022-06-03T03:31:39+00:00

ios – How would I get persistent data working in my reminder app

  • 0

[ad_1]

I have a reminder app that I am trying to implement persistent data in but whenever I close the app no data is saved. I know how to make it work with a normal MVC but I would like to get it working with the view model that I have.

I think I know what needs to change to fix the problem but I am not sure how to get to the solution. I am pretty sure that in the ReminderApp file under the NavigationView where it says HomeViewModel(reminds: store.reminds) I think that the store.reminds part needs to be binded to with a $ at the beginning but when I try doing that it doesn’t work and instead says that HomeViewModel reminds property expects Reminder instead of Binding.

ReminderStore loads and saves the reminders to a file with the reminders and HomeViewModel contains the reminders array and appends a reminder to the array when a user adds a new reminder.

If anyone knows how to get this working that would be great since I have been stuck on this. My minimal reproducable example code is below.

RemindersApp

”’

import SwiftUI

@main
struct RemindersApp: App {
@StateObject private var store = ReminderStore()

var body: some Scene {
    WindowGroup {
        NavigationView {
            HomeView(homeVM: HomeViewModel(reminds: store.reminds)) {
                ReminderStore.save(reminds: store.reminds) { result in
                    if case .failure(let error) = result {
                        fatalError(error.localizedDescription)
                    }
                }
            }
            .navigationBarHidden(true)
        }
        .onAppear {
            ReminderStore.load { result in
                switch result {
                case .failure(let error):
                    fatalError(error.localizedDescription)
                case .success(let reminds):
                    store.reminds = reminds
                }
            }
        }
    }
}
}

”’

HomeView

”’

import SwiftUI

struct HomeView: View {
@StateObject var homeVM: HomeViewModel
@Environment(\.scenePhase) private var scenePhase
@State var addView = false
let saveAction: ()->Void

var body: some View {
    VStack {
        List {
            ForEach($homeVM.reminds) { $remind in
                Text(remind.title)
            }
        }
    }
    .safeAreaInset(edge: .top) {
        HStack {
            Text("Reminders")
                .font(.title)
                .padding()
            
            Spacer()
            
            Button(action: {
                addView.toggle()
            }) {
                Image(systemName: "plus")
                    .padding()
                    .font(.title2)
            }
            .sheet(isPresented: $addView) {
                NavigationView {
                    VStack {
                        Form {
                            TextField("Title", text: $homeVM.newRemindData.title)
                        }
                    }
                        .toolbar {
                            ToolbarItem(placement: .cancellationAction) {
                                Button("Dismiss") {
                                    homeVM.newRemindData = Reminder.Data()
                                    addView.toggle()
                                }
                            }
                            ToolbarItem(placement: .principal) {
                                Text("New Reminder")
                                    .font(.title3)
                            }
                            ToolbarItem(placement: .confirmationAction) {
                                Button("Add") {
                                    homeVM.addRemindData(remindData: homeVM.newRemindData)
                                    addView.toggle()
                                }
                            }
                        }
                }
            }
            .onChange(of: scenePhase) { phase in
                if phase == .inactive { saveAction() }
            }
        }
    }
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
    HomeView(homeVM: HomeViewModel(reminds: Reminder.sampleReminders), saveAction: {})
}
}

”’

ReminderStore

”’

import Foundation
import SwiftUI

class ReminderStore: ObservableObject {
@Published var reminds: [Reminder] = []

private static func fileURL() throws -> URL {
    try FileManager.default.url(for: .documentDirectory,
                                in: .userDomainMask,
                                appropriateFor: nil,
                                create: false)
    .appendingPathComponent("reminds.data")
}

static func load(completion: @escaping (Result<[Reminder], Error>) -> Void) {
    DispatchQueue.global(qos: .background).async {
        do {
            let fileURL = try fileURL()
            guard let file = try? FileHandle(forReadingFrom: fileURL) else {
                DispatchQueue.main.async {
                    completion(.success([]))
                }
                return
            }
            let reminds = try JSONDecoder().decode([Reminder].self, from: file.availableData)
            DispatchQueue.main.async {
                completion(.success(reminds))
            }
        } catch {
            DispatchQueue.main.async {
                completion(.failure(error))
            }
        }
    }
}

static func save(reminds: [Reminder], completion: @escaping (Result<Int, Error>) -> Void) {
    do {
        let data = try JSONEncoder().encode(reminds)
        let outfile = try fileURL()
        try data.write(to: outfile)
        DispatchQueue.main.async {
            completion(.success(reminds.count))
        }
    } catch {
        DispatchQueue.main.async {
            completion(.failure(error))
        }
    }
}
}

”’

HomeViewModel

”’

import Foundation

class HomeViewModel: ObservableObject {
@Published var reminds: [Reminder]
@Published var newRemindData = Reminder.Data()

init(reminds: [Reminder]) {
    self.reminds = reminds
}

func addRemindData(remindData: Reminder.Data) {
    let newRemind = Reminder(data: remindData)
    reminds.append(newRemind)
    newRemindData = Reminder.Data()
}
}

”’

Reminder

”’

import Foundation

struct Reminder: Identifiable, Codable {
var title: String
let id: UUID

init(title: String, id: UUID = UUID()) {
    self.title = title
    self.id = id
}
}

extension Reminder {
struct Data {
    var title: String = ""
    var id: UUID = UUID()
        
}

var data: Data {
    Data(title: title)
}

mutating func update(from data: Data) {
    title = data.title
}

init(data: Data) {
    title = data.title
    id = UUID()
}
}

extension Reminder {
static var sampleReminders = [
    Reminder(title: "Reminder1"),
    Reminder(title: "Reminder2"),
    Reminder(title: "Reminder3")
]
}

”’

[ad_2]

  • 0 0 Answers
  • 1 View
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 8087 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 1871 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 1957 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.