Search code examples
swiftmacosobservableswiftui-listproperty-wrapper-published

In SwiftUI I have a List that should update when the source array in a Swift class is appended but I get syntax errors that I don't understand


I have an example project to learn how to have a List update when the source array (in a Swift class) updates. I'm pretty green in SwiftUI and Swift. The List View error is:

Initializer 'init(_:id:rowContent:)' requires that 'Published<[String]>.Publisher' conform to 'RandomAccessCollection'

Apple says that an array of String does conform to a 'RandomAccessCollection'.

XCode ver. 14.3, MacOS Ventura 13.3

This is my fourth attempt to use suggestions that I've found using Dr. Google which includes Apple docummentation; I always get syntax errors that I don't understand but my demonstration code keeps getting shorter.

My objective is to use the Calculate class to orchestrate data processsing and, from time to time, inform the user of what's been done, aka a running log. I want to append messages to the array from the Calculate class and any of its sub-classes.

The class containing the array:

import Foundation

class Calculate: ObservableObject {
    
    init() {
        // TODO later
    }
    
    @Published var messageArray = Array(arrayLiteral: String())
    
    func addMessage(msg: String) {
        messageArray.append(msg)
        print("Size of array is \(messageArray.count)") // test
    }
}

My Content View is below. The Button View is only for verifying that the code works.

import SwiftUI
import Combine


struct ContentView: View {
    @ObservedObject var calculate = Calculate()
    
    var body: some View {
        VStack {
            Button("Press Me") {  // for testing
                calculate.addMessage(msg: "Pressed")
            }  // The button action does append to the array.
            
            
            List(self.calculate.$messageArray, id: \.self) {
                message in
                Text(message)
                }
        }
        .onReceive(self.calculate.$messageArray) {
            newValue in // ??
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Solution

  • The List initializer expects an array and not publisher of an array so change the List declaration to

    List(self.calculate.messageArray, id: \.self)