Abenezer Bayeh
Abenezer Bayeh

Reputation: 95

Filtering String from Firestore database sends an error on SwiftUI

I'm working on implementing a search for a movies database stored in firestore using SwiftUI. I've tried doing filtering the movie names by the entered text as follows:

@ObservedObject var movies = getMoviesData()

...

ForEach(self.movies.datas) { movies in
  ForEach(movies.title.filter({"\($0)".contains(searchText.lowercased()) || searchText.isEmpty})) { item in
                                
     if let url = URL(string: movies.img) {
        AnimatedImage(url: url)
        .resizable()
        .frame(width: bounds.size.width / 2 - 0.6, height: bounds.size.height / 2 - 0.2)       
     }
                                
  }
  .animation(.spring())
}

...

struct movies : Identifiable {
    var id: String
    var title: String
    var img: String
    var video: String
    var description: String
    var genre: String
}

class getMoviesData : ObservableObject{
    @Published var datas = [movies]()
    private var db = Firestore.firestore()
    
    func fetchData(){
        db.collection("movies").addSnapshotListener{ (querySnapshot, error) in
            guard let mov = querySnapshot?.documents else{
                print("No movies")
                return
            }
            
            self.datas = mov.map{(queryDocumentSnapshot) -> movies in
                let data = queryDocumentSnapshot.data()
                let id = data["id"] as? String ?? ""
                let title = data["title"] as? String ?? ""
                let img = data["img"] as? String ?? ""
                let video = data["video"] as? String ?? ""
                let description = data["description"] as? String ?? ""
                let genre = data["genre"] as? String ?? ""
                
                return movies(id: id, title: title, img: img, video: video, description: description, genre: genre)
            }
        }
    }
}

However, I'm receiving the following error on the second ForEach statement:

Referencing initializer 'init(_:content:)' on 'ForEach' requires that 'String.Element' (aka 'Character') conform to 'Identifiable'

Movies.title represents a String output of each movie identified in the ForEach statement. How should I filter movies.title against the provided search text without invoking this error?

Upvotes: 1

Views: 279

Answers (1)

azamsharp
azamsharp

Reputation: 20068

I am little confused about your use of variable names.

 ForEach(movies.title.filter({"\($0)".contains(searchText.lowercased()) || searchText.isEmpty})) { item in
                                     
     }
                                
  }

In the above code movies.title is very misleading. Is there a title property on movies array. If you need to filter, you can perhaps check out the sample code below:

struct Movie {
    let title: String
}

let movies = [Movie(title: "Spiderman"), Movie(title: "Batman"), Movie(title: "Superman")]
let searchWord = "batman"


let filteredMovies = movies.filter { movie in
    return movie.title.lowercased().contains(searchWord.lowercased())
}

print(filteredMovies)

Upvotes: 1

Related Questions