Home > Net >  SwiftUI - Error - Initializer 'init(_:rowContent:)' requires that 'CustomDataModel�
SwiftUI - Error - Initializer 'init(_:rowContent:)' requires that 'CustomDataModel�

Time:07-08

In my watch app, I wish to display list of events. When the view is opened, I send a request to iPhone app to send the events list. This is working so far and I am getting the events list back to Watch. However when I try to display the data on the list, I am getting errors due to custom object type. What I want is to display the events list when the data is available or just show a text on the view when there are no events.

Note: Watch connectivity to transfer data between devices/OS's does not allow custom data types, so have to conform to Codable and convert the data from CustomDataModel to Data type before transferring and then convert from Data to CustomDataModel in my Watch project.

Below is the code and error that I see:

CustomDataModel

import Foundation

struct CustomDataModel: Codable {
    var startEndDate: String?
    
    var startEndTime: String?

    var locationDetails: String?
    
    var actions: Dictionary<String, String> = [:]
    
    var title: String?
    
    // Has more properties
    
    func encodeIt() -> Data {
        let data = try! PropertyListEncoder.init().encode(self)
        return data
    }
    
    static func decodeIt(_ data:Data) -> CustomDataModel {
        let customDataModel = try! PropertyListDecoder.init().decode(CustomDataModel.self, from: data)
        return customDataModel
    }
}

CustomViewModel

import Foundation
import Combine

class CustomViewModel: ObservableObject, SessionCommands {
    @Published var eventsList:[CustomDataModel] = []
    
    init() {
        NotificationCenter.default.addObserver(forName: Notification.Name("eventsListReady"), object: nil, queue: nil, using: self.processEventsList(_:))
    }
    
    @objc func processEventsList(_ notification: Notification) {
        if let response = (notification.object as! CommandStatus).response as? [Data] {
            response.forEach { event in
                eventsList.append(CustomDataModel.decodeIt(event))
            }
        }
     }
    
    func getEventsList() {
        self.eventsList = []
        sendMessage(["functionality": Functionality.events.rawValue, "notificationName": Notification.Name("requestEventsList")])
    }
}

CustomView

import SwiftUI

struct CustomView: View {
    @ObservedObject var viewModel: CustomViewModel
    
    var body: some View {
        VStack {
            if !viewModel.eventsList.isEmpty {
                List(viewModel.eventsList) { item in
                    let _ = print("##### !viewModel.eventsList.isEmpty")
                    NavigationLink(destination: EventsDetailsView(eventItem: item)) {
                        EventRowView(eventItem: item)
                    }.navigationViewStyle(StackNavigationViewStyle())
                }
            } else {
                let _ = print("##### viewModel.eventsList.isEmpty")
                VStack {
                    Text("No events to display")
                }.frame(maxWidth: .infinity, maxHeight: .infinity)
            }
        }.navigationBarTitle("Back").onAppear() {
            self.viewModel.getEventsList()
        }
    }
}

Error I get on "List(viewModel.eventsList)" in CustomView : Initializer 'init(_:rowContent:)' requires that 'CustomDataModel' conform to 'Identifiable'

I am getting data in eventList object in CustomViewModel, but am not able to display it.

CodePudding user response:

Give your type an id and make it identifiable and if you don’t need decidable don’t add it.

struct MyType: Encodable, Identifiable {
  let id = UUID()

  // other properties
}

Using Codable is just shorthand for adding Encodable and Decodable. So if you don’t need both, then just use the one you need.

  • Related