테이블 셀을 누르면 해당 여행지 정보를 상세 페이지로 전달하고, 이미지와 제목으로 보여줄 수 있도록 했습니다.
왼쪽 이미지에서 보이는 것은 키워드 검색 조회로 홈 화면에 보이는 테이블에 데이터를 전달할 때 사용되는 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를 통해 받아온 데이터 중 일부를 추출하여, 테이블 형태로 보여주기
'iOS > UIKIT' 카테고리의 다른 글
view.layer.masksToBounds = true와 view.clipsToBounds = true 차이 (0) | 2024.08.29 |
---|---|
Auto Layout을 사용하는 이유와 장점은 무엇인가요? (0) | 2024.08.21 |
API를 통해 받아온 데이터를 배열로 저장하고, 이를 갖고 다른 메서드에서는 어떻게 사용할 수 있나? (0) | 2024.08.20 |
API 불러온 데이터 중에서 URL 주소를 변환하기 (0) | 2024.08.19 |
UITableView를 UIView 넣어야 하나? 아니면 UIViewController에 넣어야 하나? (0) | 2024.08.16 |