Search code examples
swiftsearchswiftuicloudkit

Cannot convert value of type 'String' to expected argument type Event when searching from cloudkit


I'm trying to add a function to my ios app in which the user can search through the list of countries available in CloudKit. To do that I created a search field and I'm trying to read the data available CloudKit and retrieve it but I'm getting the following error.

Cannot convert value of type 'String' to expected argument type Event

Here is the exact location of the error. I'm new to this whole swift thing so I need some help.

This is the page with the search field

import Foundation
import SwiftUI
import CloudKit

struct Event: Identifiable{
    let record: CKRecord
    let id: CKRecord.ID
    let Country: String
    let dateTime : Date
    
    init(record: CKRecord){
        self.record = record
        self.id = record.recordID
        self.Country = record["Country"] as? String ?? ""
        self.dateTime = record["dateTime"] as? Date ?? Date.now
    }
}
struct NewCity: View {
    
    @State private var searchText = ""
    @State private var showingNatio = false
    @State private var showingNotifi = false
    @State var events :[Event] = [] 
    
    var body: some View {
        NavigationView {
            VStack{
                Text("Search for a country")
                    .font(.title.weight(.bold))
                    .foregroundColor(Color.gray)
                    .searchable(text: $searchText){
                        ForEach(events) { city in
                            RowView(city: city)
                        }
                    }.onChange(of: searchText) { searchText in
                        events = events.filter({ city in
                            city.Country.lowercased().contains(searchText)
                        })
                    }
                    .navigationTitle("Countries")
                Text("Start searching for a country \n to add it to your list")
                    .foregroundColor(Color.gray)
                    .multilineTextAlignment(.center)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    func fetchEvent(){
        events.removeAll()
        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType:"Event", predicate: predicate)
        let operation = CKQueryOperation(query: query)
        operation.recordMatchedBlock = {recordID, result in
            switch result{
            case .success(let record):
                let event = Event(record: record)
                events.append(event)
            case .failure(let error):
                print("Error:\(error.localizedDescription)")
            }
        }
        
        CKContainer.default().publicCloudDatabase.add(operation)
        
    }
}

struct NewCity_Previews: PreviewProvider {
    static var previews: some View {
        NewCity()
    }
}

This page is the row view which displays the format of each row when searched for

import Foundation
import SwiftUI
struct RowView: View {
    var city: Event
    var body: some View {
        HStack {
            VStack (alignment: .leading, spacing: 4) {
                Text (city.Country)
                    .font(.title2.weight(.semibold))
            }
        }
    }
}
struct RowView_Previews: PreviewProvider {
    static var previews: some View {
        RowView(city: Event.Country)
            .previewLayout(.sizeThatFits)
    }
}

Solution

  • Your struct RowView is defined as follows:

    struct RowView: View {
        var city: Event
        // etc
    

    So its initialiser takes an Event

    init(city: Event)
    

    You're calling it as follows:

    RowView(city: Event.Country)
    

    and Event.Country is defined as:

    let Country: String
    

    i.e a String

    hence the error message.

    You need to pass an Event when you create a RowView