0

I am developing an App for increasing productivity. My Main Goal in this file is to add Views over a dialog. Another target is to save the data in an Array for using it again with the annotation @AppStorage.

struct Task : Identifiable {
    var id = UUID()
    var myContent = "Empty"
    var myCounter = 0
}

I'm using this struct to save my data which is here mainly the tasks name.

struct TaskView : View {
    var task : Task
    
    var body: some View {
        HStack {
            Spacer()
            Text(String(task.myContent) ?? "test")
            Spacer()
            Text("Sessions today: " + String(task.myCounter))
            Spacer()
            Image(systemName: "xmark.bin.fill")
        }
    }
}

For displaying the data I'm using my own struct.

struct ItemList: View {
    
    @AppStorage("myviews") var myviews : [Task]? = nil
    @State private var showingAlert = false;
    @State private var taskName = "tim";
    
    var body: some View {
        VStack{
            if(!myviews.isEmpty){
                for task in myviews {
                    TaskView(task: task)
                }
            }
                
            Spacer()
            Button {
                showingAlert = true;
            } label: {
                Image(systemName: "plus")
                    .padding()
                    .background(Color.red)
                    .accentColor(.white)
                    .cornerRadius(100)
            }
            .alert(isPresented: $showingAlert) {
                Alert(title: Text("Important message"), message: TextField("Task: "; text: $taskName), primaryButton: .destructive(Text("Got it!")){
                    myviews.append(Task(myContent: String(taskName), myCounter: 0))
                })
                    }
            Spacer()

        }
        
    }
}

So the main part consists of my @AppStorage Array, a loop to show existing "tasks" and a Dialog to add these tasks to the array.

The Error I am getting is the "No exact matches in call to initializer" directly in the line @AppStorage("myviews") var myviews : [Task]? = nil

I already tried different variations of initializing the array until I read in a forum that leaving the initialization not optional could be a cause to my problems.

Furthermore I checked my "Text" - Fields for the wrong types and casted the Int's (myCounter) to String.

It feels like I read every StackOverflow Article regarding my Error but none could help me.

HangarRash
  • 7,314
  • 5
  • 5
  • 32
  • 3
    Does this answer your question? [Trouble implementing UserDefaults](https://stackoverflow.com/questions/69148980/trouble-implementing-userdefaults) – lorem ipsum Dec 29 '22 at 17:14
  • The above solution will work for you. However, it is not a good practice to store custom objects in the User Defaults. If you like to store multiple Task objects locally, you should use Core Data. – mucahid-erdogan Dec 29 '22 at 20:01

1 Answers1

0

You can solve that problem by add this extension.

import Foundation

extension Optional: RawRepresentable where Wrapped: Codable {
    
    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
              let result = String(data: data, encoding: .utf8) else {
            return "{}"
        }
        
        return result
    }
    
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8),
              let result = try? JSONDecoder().decode(Self.self, from: data) else {
            return nil
        }
        
        self = result
    }
}

And this...

import Foundation

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
    }
}
AngelDev
  • 106
  • 1
  • 4