let searchController = UISearchController(searchResultsController:
UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BookResultViewController") as! BookResultViewController)
func setupSearchBar(){
title = "Book Search"
navigationItem.searchController = searchController
searchController.searchResultsUpdater = self
//첫 글자 대문자로 표시안되게 하는 옵션
searchController.searchBar.autocapitalizationType = .none
}
extension ViewController: UISearchResultsUpdating{
func updateSearchResults(for searchController: UISearchController) {
let vc = searchController.searchResultsController as! BookResultViewController
vc.keyword = searchController.searchBar.text ?? ""
}
}
Cell 파일 생성할 때 Also create XIB file 체크하여 생성하기
테이블뷰에 셀 등록하기
func setupTableView(){
bookTableView.delegate = self
bookTableView.dataSource = self
// Cell.bookCellIdentifier = Cell 이름
bookTableView.register(UINib(nibName: Cell.bookCellIdentifier, bundle: nil), forCellReuseIdentifier: Cell.bookCellIdentifier)
}
View Controller에 컬렉션 뷰 추가하고 셀 내부에 이미지뷰, 레이블 추가
아이템을 한 줄에 3개씩 배치하기 위해, 컬렉션뷰의 레이아웃을 담당하는 객체 생성하기
let flowLayout = UICollectionViewFlowLayout()
func setupCollectionView(){
bookCollectionView.dataSource = self
flowLayout.scrollDirection = .vertical
let collectionCellWidth = (UIScreen.main.bounds.width - CVCell.spacingWitdh * (CVCell.cellColumns - 1)) / CVCell.cellColumns
flowLayout.itemSize = CGSize(width: collectionCellWidth, height: collectionCellWidth + 50)
// 아이템 사이 간격 설정
flowLayout.minimumInteritemSpacing = CVCell.spacingWitdh
// 아이템 위아래 사이 간격 설정
flowLayout.minimumLineSpacing = CVCell.spacingWitdh
// 컬렉션뷰의 속성에 할당
bookCollectionView.collectionViewLayout = flowLayout
}
public enum NetworkError: Error{
case networkingError
case dataError
case parseError
}
public struct NetworkManager{
// 싱글톤 패턴
static let shared = NetworkManager()
private init(){}
typealias NetworkCompletion = (Result<[Book], NetworkError>) -> (Void)
typealias BookDescriptionNetworkCompletion = (Result<String, NetworkError>) -> (Void)
func fetchBook(completion: @escaping NetworkCompletion) {
let url = "\(BookApi.allBookURL)&\(BookApi.apiKeyParam)&\(BookApi.sizeParam)"
print(url)
getBook(url) { result in
completion(result)
}
}
func getBook(_ searchUrl: String, completion: @escaping NetworkCompletion ){
guard let url = URL(string: searchUrl) else { return }
let session = URLSession(configuration: .default)
session.dataTask(with: url){ (data, response, error) in
if error != nil{
completion(.failure(.networkingError))
return
}
guard let safeData = data else {
completion(.failure(.dataError))
return
}
if let bookData = parseJSON(safeData){
completion(.success(bookData))
return
}
else
{
completion(.failure(.parseError))
return
}
}.resume()
}
func parseJSON(_ bookData: Data) -> [Book]? {
do {
let bookData = try JSONDecoder().decode(ResponseData.self, from: bookData)
var bookArray: [Book] = []
for item in bookData.response.docs{
if let book = item.doc {
bookArray.insert(book, at: bookArray.count)
}
}
return bookArray
} catch {
print(error.localizedDescription)
return nil
}
}
}