SSUMC-6th / iOS_A

SSUMC 6기 iOS 스터디 A조
0 stars 0 forks source link

[JC] 코드 리뷰 & 문제 해결 도움 요청 #27

Closed jayn2u closed 4 months ago

jayn2u commented 4 months ago

코드 리뷰 & 문제 해결 도움 요청

문제

자료

Simulator Screen Recording - iPhone 15 Pro - 2024-05-07 at 11 25 43

Code

class TableViewController: UITableViewController {
  // MARK: - Properties
  var movie = [MovieData]()

  // MARK: - Life Cycle
  override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(TableViewCell.self, forCellReuseIdentifier: TableViewCell.identifier)

    tableView.backgroundColor = .systemBackground
    self.navigationItem.title = "Now Playing"
    self.navigationController?.navigationBar.prefersLargeTitles = true

    self.fetchAPIData()
  }

  // MARK: - Methods
  private func fetchAPIData() {
    let hostUrl = "https://api.themoviedb.org/3/movie/"
    let baseImageUrlString = "https://image.tmdb.org/t/p/original"
    let apiKey = APIKey.serialNumber

    let requestUrl = URL(string: "\(hostUrl)now_playing?api_key=\(apiKey)")!
    var request = URLRequest(url: requestUrl)
    request.httpMethod = "GET"

    let task = URLSession.shared.dataTask(with: requestUrl) { data, _, error in
      if let error = error {
        debugPrint(error)
        return
      }

      guard let data = data else {
        debugPrint("There are no data")
        return
      }

      do {
        let decoder = JSONDecoder()
        let responseData = try decoder.decode(NowPlayingModel.self, from: data)

        for idx in 0..<responseData.results.count {
          let title = responseData.results[idx].title
          guard let posterPath = responseData.results[idx].posterPath else { return }
          guard let posterImageUrl = URL(string: baseImageUrlString + posterPath) else { return }
          let data = try Data(contentsOf: posterImageUrl)

          self.movie.append(MovieData(titleData: title, posterData: data))

        }
      } catch {
        debugPrint(error)
      }

      DispatchQueue.main.async {
        self.tableView.reloadData()
      }

    }

    task.resume()

  }

  // MARK: - Table view data source

  override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return movie.count
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
    -> UITableViewCell
  {
    guard
      let cell = tableView.dequeueReusableCell(
        withIdentifier: TableViewCell.identifier, for: indexPath) as? TableViewCell
    else {
      return TableViewCell()
    }

    // Configure the cell...
    cell.title.text = self.movie[indexPath.row].titleData
    cell.poster.image = UIImage(data: self.movie[indexPath.row].posterData)

    return cell
  }

  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
  {
    return 300
  }

  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let detailViewController : ViewController = {
      let viewController = ViewController()
      viewController.movieTitle = self.movie[indexPath.row].titleData
      viewController.moviePoster.image = UIImage(data: self.movie[indexPath.row].posterData)
      return viewController
    }()

    navigationController?.pushViewController(detailViewController, animated: true)
  }
}
jayn2u commented 4 months ago

여기서 발생하는 사용자 경험을 더 개선하기 위한 방법이 무엇이 있을까 고민하고 공유해봐!

다른 사람들의 생각은 어떤지 궁금해!

Joon9750 commented 4 months ago

Swift에서 테이블 뷰나 컬렉션 뷰에 스켈레톤 뷰 사용해서 로딩 애니메이션을 추가할 수 있어요. 스켈레톤 사용하면 데이터 들어오기 전까지 테이블 자체의 형태는 보여주면서 로딩 애니메이션을 띄울 수 있어요. swift skeleton animation 이렇게 검색하면 참고할 자료들 많이 나올거에요.

Joon9750 commented 4 months ago

그리고 테이블 로딩에 필요한 데이터는 사실 많지 않아요. 대신 그 테이블을 스크롤 내렸을 때 보여질 데이터들이 많아서 데이터를 받아오는데 시간이 걸리는데, 이때 페이징 기능을 추가하는 방식으로 저는 해결했어요. 물론 페이징을 위해서는 호출하는 API에도 페이징 기능이 들어가 있어야 해요.

지금은 한 번에 불러오는 데이터가 많지는 않아서 크게 느리진 않지만 나중에 데이터가 많아지면 페이징.. 없이는 쉽지 않아요.

Joon9750 commented 4 months ago

그리고 이건 다른 이야기인데, hostUrl이나 Url 정보들은 함수에서 지역변수로 관리되는것 보다 Url들을 관리하는 클래스를 따로 두고 static으로 관리하는게 수정 사항 생겼을 때 찾기가 더 쉬워요!😁

jayn2u commented 4 months ago

Swift에서 테이블 뷰나 컬렉션 뷰에 스켈레톤 뷰 사용해서 로딩 애니메이션을 추가할 수 있어요. 스켈레톤 사용하면 데이터 들어오기 전까지 테이블 자체의 형태는 보여주면서 로딩 애니메이션을 띄울 수 있어요. swift skeleton animation 이렇게 검색하면 참고할 자료들 많이 나올거에요.

이 정보는 굉장히 도움이 많이 될 것 같아. 나도 로딩 애니메이션의 필요성을 이번 데모 프로젝트를 하면서 많이 느꼈거든. 좋은 정보 공유해줘서 고마워!

그리고 테이블 로딩에 필요한 데이터는 사실 많지 않아요. 대신 그 테이블을 스크롤 내렸을 때 보여질 데이터들이 많아서 데이터를 받아오는데 시간이 걸리는데, 이때 페이징 기능을 추가하는 방식으로 저는 해결했어요. 물론 페이징을 위해서는 호출하는 API에도 페이징 기능이 들어가 있어야 해요.

지금은 한 번에 불러오는 데이터가 많지는 않아서 크게 느리진 않지만 나중에 데이터가 많아지면 페이징.. 없이는 쉽지 않아요.

아직 서버와 함께 작업하는 일은 많이 안해봐서 이 솔루션을 다루는 방법은 시도해보지 못하겠지만, 꼭 기억하고 있다가 나중에 활용해볼게!

그리고 이건 다른 이야기인데, hostUrl이나 Url 정보들은 함수에서 지역변수로 관리되는것 보다 Url들을 관리하는 클래스를 따로 두고 static으로 관리하는게 수정 사항 생겼을 때 찾기가 더 쉬워요!😁

이 정보 역시 참고자료들을 많이 확인하다보니까, URL을 지역변수로 사용하는 경우는 확실히 없더라고! 특히 콜백함수를 사용해서 completion handler로 메인 스레드에서 작업을 실행하는 코드를 많이 봤어. 생각 나누어주어서 고마워!

jayn2u commented 4 months ago

문제 해결

문제

해결

동작화면

Simulator Screen Recording - iPhone 15 Pro - 2024-05-08 at 09 57 14