/TMDBProject

TMDBProject

Primary LanguageSwift

๐ŸŽฌ ์˜ํ™” ์ˆœ์œ„ ์•ฑ

TMDB_preview

TMDB API๋ฅผ ์ด์šฉํ•ด์„œ ์˜ํ™” ์ˆœ์œ„๋ฅผ ํ™•์ธํ•˜๊ณ  ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์•ฑ์ž…๋‹ˆ๋‹ค.

  • Pagination์œผ๋กœ ์˜ํ™”์˜ ์ˆœ์œ„๋ฅผ ํ•œ ํ™”๋ฉด์—์„œ ์Šคํฌ๋กค์„ ํ†ตํ•˜์—ฌ ์†์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • CollectionView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ TOP 5 ์˜ํ™”์™€ ๋น„์Šทํ•œ ์žฅ๋ฅด์˜ ์ปจํ…์ธ ๋ฅผ ์ถ”์ฒœ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • WebKit์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งํฌ ๋ฒ„ํŠผ ์‹œ ๊ฐ ์˜ํ™”์˜ ์‹œ๋†‰์‹œ์Šค๋ฅผ ์‹œ์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • CustomCell์„ ์žฌ์‚ฌ์šฉ ํ•˜์—ฌ ์˜ํ™”์˜ ์ž์„ธํ•œ ์ •๋ณด(์˜ํ™” ์„ค๋ช…, ์ถœ์—ฐ์ง„, ์Šคํƒญ ๋“ฑ)์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • MapKit์„ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”์ฒœ ์˜ํ™”๊ด€์„ MapView๋กœ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



๐Ÿ› ๏ธ ์‚ฌ์šฉ ๊ธฐ์ˆ  ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • Swift, UIKit, Storyboard, MVC, MapKit, CLLocation, WebKit
  • Alamofire, SwiftyJSON, Kingfisher



๐Ÿ—“๏ธ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„

  • ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„: 2022๋…„ 8์›” 3์ผ ~ 2022๋…„ 8์›” 18์ผ (์•ฝ 2์ฃผ)
  • ์„ธ๋ถ€ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„
    • 2022.08.03 ~ 2022.08.06: ๊ธฐ๋ณธ UI ๋ฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„ (์˜ํ™”๋ณ„ ์ˆœ์œ„, ์ƒ์„ธ ํŽ˜์ด์ง€ ๋“ฑ)
    • 2022.08.07 ~ 2022.08.18: ๊ทธ ์™ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ (์˜ํ™” ์ถ”์ฒœ, ์˜ํ™”๊ด€ ์ถ”์ฒœ ๋“ฑ)





โœ๏ธ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ์ˆ 

  • Storyboard๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI ๊ตฌํ˜„
  • Alamofire๋ฅผ ํ™œ์šฉํ•œ API ํ†ต์‹ 
  • WebKit์„ ํ™œ์šฉํ•œ ์›นํŽ˜์ด์ง€ ์ด๋™ ๋ฐ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„.
  • ์œ„์น˜ ๊ถŒํ•œ ์„ค์ • ๋ฐ ๋Œ€์‘



๐Ÿ’ก Trouble Shooting

  • 100๊ฐœ๊ฐ€ ๋„˜๋Š” ์˜ํ™” ๋ฐ์ดํ„ฐ๋ฅผ CollectionView Cell์— ๋„ฃ์–ด์•ผ ํ•˜๋Š” ์ด์Šˆ

    โ†’ Pagenation์œผ๋กœ ๋ฐฐ์—ด์˜ ์ผ์ • ์‹œ์ ๋งˆ๋‹ค ํ†ต์‹ ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

static var searchList: [TrendListModel] = []

extension ListViewController: UICollectionViewDataSourcePrefetching {
    func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
        for indexPath in indexPaths {
            if ListViewController.searchList.count - 5 == indexPath.item && ListViewController.searchList.count < totalCount {
                startPage += 1
                requestTMDBTrend(media_type: mediaType, time_window: timeWindow, page: startPage)
            }
        }
    }
}



  • ๋น„์Šทํ•œ ์ปจํ…์ธ ์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ์…€์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋ฐ”๋€Œ์–ด์•ผ ํ•˜๋Š” ์ด์Šˆ

    โ†’ TableViewCell ๋‚ด CollectionView๋ฅผ ๋„ฃ๊ณ  CollectionView์—๊ฒŒ ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ ํ•ด๊ฒฐ

    TMDB_issue
class RecommandTableViewCell: UITableViewCell {

    @IBOutlet weak var recommandCollectionView: UICollectionView!
    @IBOutlet weak var titleLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()

        setupUI()

    }

    func setupUI() {
        titleLabel.font = UIFont(name: "Binggrae-Bold", size: 17)
        titleLabel.text = ""
        recommandCollectionView.backgroundColor = .clear
        recommandCollectionView.collectionViewLayout = collectionViewLayout()
    }

    func collectionViewLayout() -> UICollectionViewFlowLayout {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.itemSize = CGSize(width: 100, height: 150)
        layout.minimumLineSpacing = 16
        layout.minimumInteritemSpacing = 16
        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0)

        return layout
    }
}





๐Ÿค” ํšŒ๊ณ 

  • UserDefaults๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Key๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” String์„ ์‚ฌ์šฉํ•  ๋•Œ ๋งˆ๋‹ค raw๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ถ”ํ›„ ๋ฆฌํŒฉํ† ๋ง ์‹œ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ณ , ๊ฐœ๋ฐœ์ž์˜ ์‹ค์ˆ˜๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ์ถ”ํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ raw๊ฐ’์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ•จ์„ ๋Š๊ผˆ๊ณ , ์ดํ›„ ๋ฐ˜๊ธฐ๋‹ค ํ”„๋กœ์ ํŠธ์—์„œ ์—ด๊ฑฐํ˜•์œผ๋กœ raw๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•˜์—ฌ ์ถ”ํ›„ ์œ ์ง€โ€ข๋ณด์ˆ˜์—๋„ ๋น„์šฉ์ด ์ ๊ฒŒ ๋“ค๋„๋ก ์„ค๊ณ„ํ–ˆ๋‹ค.
  • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์—์„œ ๋„ค์ด๋ฐ์„ ๋ดค์„ ๋•Œ ๋ฉ”์„œ๋“œ๋‚˜ ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ •ํ™•ํ•˜๊ฒŒ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ์ถ”ํ›„ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ํ˜‘์—…์— ๋Œ€๋น„ํ•˜์—ฌ ๋„ค์ด๋ฐ์„ ๋” ์ง๊ด€์ ์ด๊ณ  ํ•œ ๋ฒˆ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋Š๊ผˆ๋‹ค.
  • API ํ†ต์‹  ์‹œ Error์— ๋Œ€ํ•œ ๋Œ€์‘์ด ๋ฏธ์ˆ™ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋Š๊ผˆ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ API ํ†ต์‹ ์— ์‹คํŒจํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ถ”ํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ Error์— ๊ด€ํ•œ ๋Œ€์‘์˜ ํ•„์š”์„ฑ์„ ๋Š๊ผˆ๊ณ , ์ดํ›„ ์ƒˆ์‹น ์Šคํ„ฐ๋”” ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ ๋„คํŠธ์›Œํฌ ํ†ต์‹  ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” Error๋ฅผ ๋Œ€์‘ํ–ˆ๋‹ค.