我解析了一个来自iTunes API的数据模型:
struct AlbumData: Codable {
let results: [Result]
}
struct Result: Codable {
let artistName, collectionName: String
let trackCount: Int
let releaseDate: String
let artworkUrl100: String
}
struct AlbumModel {
let albumsResult: [Result]
}
,这是NetworkService代码:
import Foundation
protocol NetworkServiceDelegate {
func updateInfo (_ manager: NetworkService, album: AlbumModel)
func errorInfo (error: Error)
}
struct NetworkService {
var delegate: NetworkServiceDelegate?
func fetchAlbums () {
let urlString = "https://itunes.apple.com/search?term=eminem&limit=8&entity=album"
performRequest(with: urlString)
}
func performRequest(with urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
delegate?.errorInfo(error: error!)
print("Debuggg error (LocalizedError.self)")
}
if let safeData = data {
if let albums = self.parseJSON(safeData) {
delegate?.updateInfo(self, album: albums)
print("succses - (albums)")
}
}
}
task.resume()
}
}
func parseJSON(_ data: Data) -> AlbumModel? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(AlbumData.self, from: data)
let result = decodedData.results
let album = AlbumModel(albumsResult: result)
return album
} catch {
print(error)
return nil
}
}
}
之后,我将这个数据添加到数组中:
var albums: [AlbumModel] = []
现在我有了这样的数组:
[Itunes_Albums.AlbumModel(albumsResult: [Itunes_Albums_.Result(artistName: "Eminem", collectionName: "The Eminem Show", trackCount: 20, releaseDate: "2002-01-01T08:00:00Z", artworkUrl100: "https://is5-ssl.mzstatic.com/image/thumb/Music115/v4/61/d5/0a/61d50a3d-4a27-187a-d16f-6b8ce4b62560/source/100x100bb.jpg"), Itunes_Albums_.Result(artistName: "Eminem", collectionName: "Recovery (Deluxe Edition)", trackCount: 19, releaseDate: "2010-06-21T07:00:00Z", artworkUrl100: "https://is5-ssl.mzstatic.com/image/thumb/Music125/v4/f1/40/ce/f140ce18-f176-7cf9-c220-3958d7747ae6/source/100x100bb.jpg")
之后,我将这些数据显示到集合视图
我SearchViewController
之后,我想写一些字符搜索栏(名称的专辑)和显示专辑,但它不工作。
我可以显示所有的代码:
import UIKit
class SearchViewController: UIViewController {
@IBOutlet weak var albumCollectionView: UICollectionView!
var albums: [AlbumModel] = []
var albumsForSearch: [AlbumModel] = []
var networkService = NetworkService()
override func viewDidLoad() {
super.viewDidLoad()
title = "Search"
registerCells()
networkService.delegate = self
networkService.fetchAlbums()
}
private func registerCells() {
albumCollectionView.register(UINib(nibName: AlbumCollectionViewCell.identifier, bundle: nil), forCellWithReuseIdentifier: AlbumCollectionViewCell.identifier)
}
}
//MARK: - AlbumManagerDelegate
extension SearchViewController: NetworkServiceDelegate {
func updateInfo(_ manager: NetworkService, album: AlbumModel) {
DispatchQueue.main.async {
self.albums.append(album)
self.albumsForSearch = self.albums
print("CHEEEEEK - (self.albums)")
self.albumCollectionView.reloadData()
}
}
func errorInfo(error: Error) {
print(error)
}
}
//MARK: - UICollectionViewDelegate, UICollectionViewDataSource
extension SearchViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return albums.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return albums[section].albumsResult.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AlbumCollectionViewCell.identifier, for: indexPath)
as! AlbumCollectionViewCell
let jData = albums[indexPath.section].albumsResult[indexPath.item]
cell.albumNameLabel.text = jData.collectionName
cell.artistNameLabel.text = jData.artistName
cell.numberOfTracksLabel.text = "(jData.trackCount) song(s)"
cell.albumImage.load(urlString: "(jData.artworkUrl100)")
cell.dateOfRelease.text = jData.releaseDate.substring(toIndex: 10)
return cell
}
}
//MARK: - UISearchBarDelegate
extension SearchViewController: UISearchBarDelegate, UISearchResultsUpdating {
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let searchView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CollectionReusableView", for: indexPath)
return searchView
}
func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty {
albumsForSearch = albums.filter { album -> Bool in
return album.albumsResult.contains { item -> Bool in item.collectionName.lowercased().contains(searchText)
}
}
albumCollectionView.reloadData()
} else {
albumsForSearch = albums
}
}
}
当我在搜索栏中输入一些字符时,没有任何变化
不知道你到底在纠结什么,所以我只是指出一些事情,希望这能解决你的问题。
首先,我不知道你的AlbumModel
长什么样。也许您可以显示这段代码。但是看起来每个实例包含不止一个albumsResult。您是否期望在这个数组中的albumsResult中只有一个对象?
如果没有,我发现这行真的很奇怪item.albumsResult[0]
。有可能发生崩溃。因此,我的答案并不假设该数组中总是有一个(且只有一个)项。
第二,我也觉得这个很奇怪:
} else {
searching = false
albumsForSearch.removeAll()
albumsForSearch = albums
}
每次找不到结果时,都要重置数组。我不确定我能想出一个合理的理由,为什么你会想要那样做。
也许这段代码就是你需要的:
if let searchText = let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty {
// Search text means filter results
albumsForSearch = albums.filter { album -> Bool in
return album.albumResult.contains { item -> Bool in
item.collectionName.lowercased().contains(searchText)
}
}
} else {
// No search text means display everything
albumsForSearch = albums
}
然后根据albumsForSearch
创建tableview分段和行