5

I am Working on an App in XCode that Displays Locations saved on a JSON file from an URL. I have saved the users favorite Locations in the UserDefaults.standard.object(forKey: "heart")

The heart button on the SpotDetailView saves the spot and also displays whether it is a favorite or not.

import SwiftUI

struct SpotDetailView: View {
    @State var spot: WindApp //knows which spot it's at
    var spotname:String
    @State var favourites: [String:String] = UserDefaults.standard.object(forKey: "heart") as? [String:String] ?? [:]
    
    
    var body: some View {
        
        ZStack {
            
            List {
                SpotMapView(coordinate: spot.locationCoordinate)
                    .cornerRadius(8)
                ForEach(0..<9) { i in
                    SingleDayView(spot: spot, counter: (i * 8))
                    }
            }
            .navigationTitle("\(spot.spot)")
            VStack {
                Spacer()
                HStack {
                    Spacer()
                    Button(action: {
                        if favourites[spot.spot] == "heart" {
                            favourites[spot.spot] = "heart.fill"
                            UserDefaults.standard.set(favourites, forKey: "heart")
                        }
                        else if favourites[spot.spot] == "heart.fill" {
                            favourites[spot.spot] = "heart"
                            UserDefaults.standard.set(favourites, forKey: "heart")
                        }
                        else {
                            favourites[spot.spot] = "heart.fill"
                            UserDefaults.standard.set(favourites, forKey: "heart")
                        }

                    }, label: {
                        Image(systemName: favourites[spot.spot] ?? "heart")
                    })
             
                }
            }
        }
    }
}

However, when trying to access the data on the main Overview it works after re/starting the app but does not update when changed in the subview.

struct AllSpotsView: View {
    @State private var spotData = [WindApp]()
    @State var favourites: [String: String] = UserDefaults.standard.object(forKey: "heart") as? [String: String] ?? [:]


    
    var body: some View {
        ZStack {
            NavigationView{
                List(spotData, id: \.spot) {
                    item in
                    NavigationLink(destination: SpotDetailView(spot: item, spotname: item.spot)) {
                        HStack() {
                            Text(item.spot)
                            
                            Text(item.country_code)
                                .font(.caption2)
                                .foregroundColor(.gray)
                            Spacer()
                            Image(systemName: favourites[item.spot] ?? "heart" )
                            
                        }
                        
                    }.navigationBarTitle("Spots")
                    
                }.onAppear(perform: loadData)
                
                
            }
                
        }
    }
}

The function loadData simply loads the JSON file from an URL. How can I make the view update once the Userdefault value changes? Thanks in advance!

pawello2222
  • 46,897
  • 22
  • 145
  • 209

1 Answers1

5

Instead of

@State var favourites: [String: String] = UserDefaults.standard.object(forKey: "heart") as? [String: String] ?? [:]

use

@AppStorage("heart") var favourites: [String: String] = [:]
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • With doing that I get the Error: "No exact matches in call to initalizer" Do I have to do anything else? And do I need to replace it at both the mainview and the subview? – Vico Seemann Dec 20 '20 at 11:52