How to pull in the data from MenuListItemModel.swift
ObservableObject classes to load into FriendshipListView.swift
and WealthListView.swift
. The WealthListView.swift
is loading the same data as FriendshipListView.swift
. Also, do I have to do something with @AppStorage
so each list saves the states properly?
MenuApp.swift
import SwiftUI
@main
struct ManifestationMenuApp: App {
@AppStorage("isOnboarding") var isOnboarding: Bool = true
var body: some Scene {
WindowGroup {
if isOnboarding {
OnboardingView()
} else {
MainView()
.environmentObject(MenuListFriendshipModel())
.environmentObject(MenuListWealthModel())
}
}
}
}
MenuListItemModel.swift
import SwiftUI
struct MenuListItemModel: Identifiable, Codable {
var id: String = UUID().uuidString
var title: String
var description: String
var isCompleted: Bool
}
MenuListFriendshipModel.swift
import SwiftUI
//use array in @Appstorage
extension Array: RawRepresentable where Element: Codable{
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let result = try? JSONDecoder().decode([Element].self, from: data)
else {
return nil
}
self = result
}
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let result = String(data: data, encoding: .utf8)
else {
return ""
}
return result
}
}
class MenuListFriendshipModel: ObservableObject {
// this loads and saves the items automatic to UserDefaults
@AppStorage("task_items_list") var items: [MenuListItemModel] = []
init() {
// fill the collection only if it is empty
if items.isEmpty{
myTaskItems()
}
}
func myTaskItems() {
items = [
MenuListItemModel(title: "I am grateful to have close and meaningful relationships.", description: "My relationships are healthy and enduring, whether with friends, colleagues, family, or romantic contacts.", isCompleted: false),
MenuListItemModel(title: "My relationships are fun and rewarding", description: "(e.g., exciting, generous, etc.) ",isCompleted: false),
MenuListItemModel(title: "No matter how long my relationships last, they are experiences I cherish.", description: "Thirty years or thirty minutes, my relationships are not judged on how long they last but on their meaningful moments.",isCompleted: false),
MenuListItemModel(title: "I treat my friends as I wish them to treat me.", description: "I am grateful for the wisdom to know when my friends and loved ones need my understanding, advice, or ears.",isCompleted: false),
MenuListItemModel(title: "I have a few friends whom I love.", description: "I realize how fortunate I am to have a few close friends who are always by my side through good and bad times.",isCompleted: false),
MenuListItemModel(title: "My friends are great at finding new ways for us to be together. ", description: "We are never out of ideas on how to create excellent and meaningful moments together.",isCompleted: false),
MenuListItemModel(title: "I am fine without relationships.", description: "I do not shun relationships, but I do not find them necessary for a meaningful life.",isCompleted: false),
MenuListItemModel(title: "I am open to making new friends.", description: "Each new friend is a new world to discover; the more, the merrier.",isCompleted: false)
]
}
}
class MenuListWealthModel: ObservableObject {
// this loads and saves the items automatic to UserDefaults
@AppStorage("task_items_list") var items: [MenuListItemModel] = []
init() {
//fill the collection only if it is empty
if items.isEmpty{
myTaskItems()
}
}
func myTaskItems() {
items = [
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false),
MenuListItemModel(title: "Test", description: "testing",isCompleted: false)
]
}
}
MenuListRowView.swift
import SwiftUI
struct MenuListRowView: View {
// This binding will assure changes will bubble up into the ViewModel represents the state of model data that will be saved in UserDefaults
@Binding var item: MenuListItemModel
var body: some View {
HStack(alignment: .top) {
Image(systemName: item.isCompleted ? "checkmark.circle" : "circle") //.imageScale(.large)
.foregroundColor(item.isCompleted ? .green : .gray)
.font(.system(size: 30, weight: .bold))
.padding(.top, 6)
VStack(alignment: .leading, spacing: 8) {
Text(item.title)
.font(.title3.bold())
Text(item.description)
.font(.body)
}
Spacer()
}
.padding(.vertical, 8)
.onTapGesture {
item.isCompleted.toggle()
}
}
}
FriendshipListView.swift
import SwiftUI
struct FriendshipListView: View {
@EnvironmentObject var listViewModel: MenuListFriendshipModel
var body: some View {
NavigationView {
List {
//Use the $ syntax to pass a binding on to the subviews
ForEach($listViewModel.items) { $item in
MenuListRowView(item: $item)
}
}
.navigationBarTitle(Text("Friendships / Relationships"))
.listStyle(PlainListStyle())
}
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
FriendshipListView()
.environmentObject(MenuListFriendshipModel())
}
}
WealthListView.swift
import SwiftUI
struct WealthListView: View {
@EnvironmentObject var listViewModel: MenuListWealthModel
var body: some View {
NavigationView {
List {
//Use the $ syntax to pass a binding on to the subviews
ForEach($listViewModel.items) { $item in
MenuListRowView(item: $item)
}
}
.navigationBarTitle(Text("Money / Wealth / Security"))
.listStyle(PlainListStyle())
}
}
}
struct WealthListView_Previews: PreviewProvider {
static var previews: some View {
WealthListView()
.environmentObject(MenuListWealthModel())
}
}
CodePudding user response:
Well your items are the same because you use the same key for @AppStorage
. The key defines where this is saved. So when you are checking for your items in MenuListWealthModel
there are allready items there and nothing is added.
//here is the error
@AppStorage("task_items_list") var items: [MenuListItemModel] = []
Change the key to be something different in MenuListWealthModel
e.g.:
@AppStorage("task_items_list_for_wealth") var items: [MenuListItemModel] = []
Remarks:
Don´t call these MenuListWealthModel
and MenuListFriendshipModel
. These are Viewmodel
classes and not Model
´s. It could only lead to confusion.