iOS/UIKIT

테이블 셀을 눌렀을 때 상세페이지로 데이터 전달하기

밤새는 탐험가89 2024. 8. 21. 01:24

 

 

테이블 셀을 누르면 해당 여행지 정보를 상세 페이지로 전달하고, 이미지와 제목으로 보여줄 수 있도록 했습니다. 

 

왼쪽 이미지에서 보이는 것은 키워드 검색 조회로 홈 화면에 보이는 테이블에 데이터를 전달할 때 사용되는 API 요청 변수 입니다. 

오른쪽 이미지는 소개 정보 조회로 여행지에 대한 상세 정보를 알려주는 API 요청 변수 입니다. 

 

 

이번에 제가 구현해볼 내용은 다음과 같습니다. 

테이블을 누르면 해당 셀에 대한 정보 중에 contentid와 contenttyepid를 DetailViewController로 전달합니다. 

그럼 DetailViewController에서는 전달 받은 contentid와 contenttypeid를 통해 소개 정보 조회 API의 파라미터로 사용합니다. 

소개 정보 조회 API를 통해 얻어온 데이터를 DetailViewController 내에 보여줍니다. 

 

 

1. DetailViewController에서 데이터를 받을 수 있도록 준비

먼저 DetailViewController에서 contentid와 contenttypeid를 받을 변수를 만들어야 합니다.

import UIKit

class DetailViewController: UIViewController {
    
    var contentId: String?
    var contentTypeId: String?
    var detailAttractionData: [Item] = []

 

 

2. HomeViewController에서 데이터를 전달할 수 있도록 준비 

HomeViewController에서 선택한 셀에 대한 정보 중에서 contentid와 contenttypeid를 전달합니다. 

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let selectedItem = attractionsWithImages[indexPath.row]
        
        let detailVC = DetailViewController()
        
        detailVC.contentId = selectedItem.contentid
        detailVC.contentTypeId = selectedItem.contenttypeid
        
        self.navigationController?.pushViewController(detailVC, animated: true)
        
    }

 

 

3. 소개 정보 조회 API를 호출할 함수 구현

contentid와 contenttypeid를 파라미터로 받아 API를 호출하는 함수를 생성합니다.

 func getDetailAttractionData(contentId: String, contentTypeId: String, completion: @escaping (Result<[Item], Error>) -> Void) {
        
        guard let url = URL(string: "\(Constants.baseURL)/B551011/KorService1/detailCommon1?serviceKey=jlK%2B0ig7iLAbdOuTJsnkp6n0RdeEMtGKsw53jEMbKm3PcB7NFTSeUrnXixogiuvNtHQXeqxgV88buRZvTjG73w%3D%3D&MobileOS=ETC&MobileApp=AppTest&_type=json&contentId=\(contentId)&contentTypeId=\(contentTypeId)&defaultYN=Y&firstImageYN=Y&areacodeYN=Y&catcodeYN=Y&addrinfoYN=Y&mapinfoYN=Y&overviewYN=Y&numOfRows=10&pageNo=1" ) else { return }
        
        let task = URLSession.shared.dataTask(with: URLRequest(url: url)) { data, _, error in
            guard let data = data, error == nil else { return }
            
            do {
                let results = try JSONDecoder().decode(AttractionResponse.self, from: data)
                completion(.success(results.response.body.items.item))
            } catch {
                completion(.failure(APIError.failedToGetData))
            }
        }
        task.resume()
    }

 

 

이때 소개 정보 조회 API의 데이터 모델을 따로 생성하지 않고, 기존의 AttractionResponse 모델에서 필요한 부분만 추가하여, 공용으로 사용할 수 있도록 했습니다. 

 

import Foundation

// MARK: - Item
struct Item: Codable {
    let addr1: String
    let addr2: String?
    let areacode: String
    let booktour: String
    let cat1: String
    let cat2: String
    let cat3: String
    let contentid: String
    let contenttypeid: String
    let createdtime: String
    let firstimage: String?
    let firstimage2: String?
    let cpyrhtDivCd: String
    let mapx: String
    let mapy: String
    let mlevel: String
    let modifiedtime: String
    let sigungucode: String
    let tel: String?
    let title: String
    
    // 추가 - 소개 정보 조회
    let homepage: String?
    let overview: String?
}

// MARK: - Items
struct Items: Codable {
    let item: [Item]
}

// MARK: - Body
struct Body: Codable {
    let items: Items
}

// MARK: - Header
struct Header: Codable {
    let resultCode: String
    let resultMsg: String
}

// MARK: - Response
struct Response: Codable {
    let header: Header
    let body: Body
}

// MARK: - AttractionResponse
struct AttractionResponse: Codable {
    let response: Response
}

 

 

4. DetailHeaderView, DetailContentView 내에 API를 통해 받은 데이터를 화면에 표시하기 위한 함수 생성 

    func configureWithImage(posterPath: String) {
        let securePosterURL = posterPath.replacingOccurrences(of: "http://", with: "https://")
        
        if let url = URL(string: securePosterURL){
            detailImageView.sd_setImage(with: url)
        } else {
            detailImageView.image = UIImage(systemName: "house")
        }
    }

 

   func configureTitleAddress(title: String, address: String) {
        
        let modifiedtitle = title.removingParentheses()
        detailTitleLabel.text = modifiedtitle
        detailAddressLabel.text = address
        
    }

5. DetailViewController 내에서 소개 정보 조회 API 호출

  override func viewDidLoad() {
        super.viewDidLoad()
       ...
        fetchData()
    }
    
    private func fetchData() {
        guard let id = contentId, let type = contentTypeId else { return }
        getDetailAttractionData(id: id, type: type)
    }
    
    private func getDetailAttractionData(id: String, type: String) {
        
        NetworkManager.shared.getDetailAttractionData(contentId: id, contentTypeId: type) { results in
            switch results {
            case .success(let item):
                guard let firstItem = item.first else { return }
                let posterPath = firstItem.firstimage
                let title = firstItem.title
                let address = firstItem.addr1
                
                DispatchQueue.main.async {
                    self.getHeaderViewImage(posterPath: posterPath!)
                    self.getDetailTitleAddress(title: title, address: address)
                    print(posterPath!)
                    
                }
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
    
    private func getHeaderViewImage(posterPath: String) {
        detailHeaderView.configureWithImage(posterPath: posterPath)
    }
    
    private func getDetailTitleAddress(title: String, address: String) {
        detailContentView.configureTitleAddress(title: title, address: address)
    }

 

 

추가로 해볼 것

소개 정보 조회 API를 통해 받아온 데이터 중 일부를 추출하여, 테이블 형태로 보여주기