본문 바로가기

UIKIT

검색결과를 카테고리별로 구분하기

 

// MARK: - Variables
// var spotResults: [AttractionItem] = []
var spotResultsByContentTypeId: [String: [AttractionItem]] = [:]   // contentTypeId별로 데이터 저장
var showAllItems: Set<String> = []  // 더 보기를 누른 contentTypeId를 저장

 

 

/// 검색어를 갖고 외부API를 통해 데이터를 불러오는 함수
func searchForKeyword(with keyword: String) {
    NetworkManager.shared.searchKeywordList(keyword: keyword) { [weak self] results in
        switch results {
        case .success(let items):
            let searchList = items.response.body.items.item

            DispatchQueue.main.async {
                // 검색 결과가 있으면 테이블 뷰를 표시하고 없으면 숨깁니다.
                self?.categorizeByContentTypeId(searchList)
                self?.spotResultsTableView.isHidden = searchList.isEmpty
                self?.spotResultsTableView.reloadData()
            }

        case .failure(let error):
            print(error.localizedDescription)
        }
    }
}

/// AttractionItem 배열인 items를 contentTypeId별로 그룹화, spotResultsByContentTypeId에 저장하는 메서드
func categorizeByContentTypeId(_ items: [AttractionItem]) {
    spotResultsByContentTypeId.removeAll()
    for item in items {
        let contenttypeid = item.contenttypeid
        // default: [] 구문을 사용하면, contentTypeId 키가 spotResults 딕셔너리에 없을 경우 빈 배열 []이 자동으로 초기화
        //
        spotResultsByContentTypeId[contenttypeid, default: []].append(item)
    }
}

 

 

// MARK: - UITableViewDelegate, UITableViewDataSource
extension SearchViewController: UITableViewDelegate, UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return spotResultsByContentTypeId.keys.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // spotResultsByContentTypeId의 키를 배열로 변환, section 번호에 해당하는 키를 할당
        let contentTypeId = Array(spotResultsByContentTypeId.keys)[section]
        let items = spotResultsByContentTypeId[contentTypeId] ?? []
        return showAllItems.contains(contentTypeId) ? items.count : min(items.count, 4)
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let contentTypeId = Array(spotResultsByContentTypeId.keys)[indexPath.section]
        let items = spotResultsByContentTypeId[contentTypeId] ?? []
        cell.textLabel?.text = items[indexPath.row].title
        return cell
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let contentTypeId = Array(spotResultsByContentTypeId.keys)[section]
        
        switch contentTypeId {
        case "12":
            return "관광지"
        case "14":
            return "문화시설"
        case "15":
            return "축제/공연/행사"
        case "25":
            return "여행코스"
        case "28":
            return "레포츠"
        case "32":
            return "숙박"
        case "38":
            return "쇼핑"
        case "39":
            return "음식점"
        default:
            return "기타"
        }
    }
}

 

 

  • 검색 결과가 1페이지 10개씩 나옵니다. 
  • 따라서 검색한 결과 모든 contentTypeId에 해당하는 값이 나오지 않습니다. 
  • 모든 contentTypeId에 해당하는 검색 결과를 5개를 보여주고, 더보기 버튼을 누를 경우 해당 contentTypeId의 데이터를 추가로 보여주는 방식으로 할 예정입니다.