首页 > 解决方案 > 从 Firestore 数据库中过滤字符串在 SwiftUI 上发送错误

问题描述

我正在使用 SwiftUI 实现对存储在 firestore 中的电影数据库的搜索。我尝试通过输入的文本过滤电影名称,如下所示:

@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)
            }
        }
    }
}

但是,我在第二个 ForEach 语句中收到以下错误:

在“ForEach”上引用初始化程序“init(_:content:)”要求“String.Element”(又名“Character”)符合“Identifiable”

Movies.title 表示 ForEach 语句中标识的每部电影的字符串输出。我应该如何在不调用此错误的情况下根据提供的搜索文本过滤 movies.title ?

标签: filtergoogle-cloud-firestoreswiftui

解决方案


我对您使用变量名有点困惑。

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

在上面的代码中 movies.title 非常具有误导性。电影数组上是否有标题属性。如果您需要过滤,您可以查看下面的示例代码:

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)

推荐阅读