Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

박스오피스 앱 [STEP 4] Matthew, Kyle #57

Open
wants to merge 41 commits into
base: d_Matthew
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b6b4dc6
feat: UIScrollView 구현
kimbs5899 Mar 8, 2024
dfbeca1
feat: UIScrollView에서 사용할 StackView구현
kimbs5899 Mar 8, 2024
cf250e9
refactor: UIScrollView 추가를 위한 기존 로직 수정
kimbs5899 Mar 8, 2024
7fa5b74
feat: 검색 REST API 모델 구현
Changhyun-Kyle Mar 8, 2024
553324d
chore: 불필요 인덴트 제거
Changhyun-Kyle Mar 8, 2024
4cdee98
refactor: NetworkURL 리팩토링 적용
kimbs5899 Mar 10, 2024
2e5a676
refactor: DataTask URLRequest로 구현로직 생성
kimbs5899 Mar 10, 2024
471108a
refactor: Kakao 검색 API를 위한 URLRequest 생성 로직 구현
kimbs5899 Mar 10, 2024
0f1d566
refactor: 영화 이미지 API 기능 구현
kimbs5899 Mar 10, 2024
cac53ec
fix: Json 디코딩 타입 수정
kimbs5899 Mar 10, 2024
d8d52e6
refactor: 영화포스터 뷰에 추가
kimbs5899 Mar 10, 2024
73a4e21
refactor: Step4 기능 로직 구현중
kimbs5899 Mar 10, 2024
bb09d06
chore: 불필요 파일 삭제 및 에셋 이미지 추가
Changhyun-Kyle Mar 15, 2024
0ac9e35
test: 유닛 테스트 로직 작성 중
Changhyun-Kyle Mar 15, 2024
8f239b1
fix: numberOfLines -> 0으로 수정
Changhyun-Kyle Mar 15, 2024
58db67d
chore: Step3 로직 반영
Changhyun-Kyle Mar 15, 2024
60eafb3
feat: BoxOfficeDetailView 데이터 패치 구현
Changhyun-Kyle Mar 15, 2024
186da18
refactor: URLSession 패치 로직 변경에 따른 프로토콜 수정
Changhyun-Kyle Mar 15, 2024
4129046
chore: 프로퍼티 및 메서드 은닉화
Changhyun-Kyle Mar 15, 2024
0dfffa6
refactor: 기존 completion Handler -> async await 로직으로 리팩토링
Changhyun-Kyle Mar 15, 2024
a7b94c1
refactor: 기존 url 패치 로직 -> urlRequest 패치로 리팩토링
Changhyun-Kyle Mar 15, 2024
12ed889
chore: Step3 로직 반영
Changhyun-Kyle Mar 15, 2024
217aa92
feat: makeDateFormat 구현
Changhyun-Kyle Mar 15, 2024
85d731a
refactor: 기존 completion Handler -> async await 로직으로 리팩토링
Changhyun-Kyle Mar 15, 2024
4fa307a
refactor: 기존 completion Handler -> async await 로직으로 리팩토링
Changhyun-Kyle Mar 15, 2024
fd6e46b
Merge pull request #4 from kimbs5899/Step4_temp
Changhyun-Kyle Mar 15, 2024
a49e293
add: URLRequest 생성 파일 추가
Changhyun-Kyle Mar 19, 2024
8df6464
remove: 불필요 테스트 파일 삭제
Changhyun-Kyle Mar 19, 2024
fa5fcf2
feat: URLRequest 생성 로직 구현
Changhyun-Kyle Mar 19, 2024
85d4759
refactor: URLRequest 생성 로직 리팩토링
Changhyun-Kyle Mar 19, 2024
5a36a52
test: 로직 리팩토링에 따른 테스트 코드 수정
Changhyun-Kyle Mar 19, 2024
e4e760d
feat: 영화 포스터 이미지 사이즈 수정
Changhyun-Kyle Mar 19, 2024
c7dcd5c
chore: NetworkURL 폴더링 수정
Changhyun-Kyle Mar 19, 2024
1419c9c
Merge branch 'd_Matthew' into Step4
Changhyun-Kyle Mar 19, 2024
8025c2a
chore: 테스트 로직 변경
Changhyun-Kyle Mar 19, 2024
296fc81
chore: BDD 주석 추가
Changhyun-Kyle Mar 19, 2024
a15fe3a
chore: 네트워크 통신 파일 추가 및 삭제
Changhyun-Kyle Mar 25, 2024
c5f2c2b
feat: URLRequest 생성 로직 리팩토링
Changhyun-Kyle Mar 25, 2024
7afcf0c
refactor: enum 타입으로 수정 후 View마다 대응할 수 있게 리팩토링
Changhyun-Kyle Mar 25, 2024
5356d9c
refactor: 수정된 로직에 따라 리팩토링
Changhyun-Kyle Mar 25, 2024
9b840be
refactor: 수정된 indicator 로직에 따라 리팩토링
Changhyun-Kyle Mar 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 70 additions & 12 deletions BoxOffice.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions BoxOffice/Controller/BoxOfficeDetailViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// BoxOfficeDetailViewController.swift
// BoxOffice
//
// Created by Matthew on 3/8/24.
//

import UIKit

final class BoxOfficeDetailViewController: UIViewController {
private let movieName: String
private let movieCode: String
private let movieManager: MovieManager
private let scrollView = BoxOfficeDetailView()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BoxOfficeDetailView가 ScrollView를 상속받고 있긴 하지만 하는 역할은 영화 상세 페이지에 대한 UI가 담겨 있는 것 같습니다.
그에 맞게 네이밍이 수정되면 좋을 것 같아요.

Copy link

@kimbs5899 kimbs5899 Mar 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! boxOfficeDetaiView로 수정하여 반영하도록 하겠습니다~!


init(
movieName: String,
movieCode: String,
movieManager: MovieManager
) {
self.movieName = movieName
self.movieCode = movieCode
self.movieManager = movieManager
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
setupView()
fetchBoxOfficeDetailData()
}
}

private extension BoxOfficeDetailViewController {
func setupView() {
LoadingIndicatorView.showLoading()
view = scrollView
view.backgroundColor = .white
self.title = movieName
}

func fetchBoxOfficeDetailData() {
Task {
do {
try await fetchMoiveImageURL()
try await fetchMovieInfo()
try await setupMovieImage()
} catch {
print(error.localizedDescription)
}
LoadingIndicatorView.hideLoading()
}
}

func fetchMovieInfo() async throws {
let data = try await movieManager.fetchMovieInfoResultData(code: movieCode)
self.scrollView.setupDetailView(data: data)
}

func fetchMoiveImageURL() async throws {
try await movieManager.fetchMoiveImageURL(movieName: movieName)
}

func setupMovieImage() async throws {
guard let data = try await movieManager.fetchImageData() else { return }
self.scrollView.setupImage(image: UIImage(data: data))
}
}
63 changes: 39 additions & 24 deletions BoxOffice/Controller/BoxOfficeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ final class BoxOfficeViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
boxOfficeListView.boxOfficeListDelegate = self
boxOfficeListView.delegate = self
boxOfficeListView.dataSource = dataSource
view = boxOfficeListView
setupBoxOfficeListView()
setupBoxOfficeData()
}
}
Expand All @@ -40,13 +37,22 @@ private extension BoxOfficeViewController {
self.title = Date.titleDateFormatter.string(from: date)
}

func setupBoxOfficeListView() {
LoadingIndicatorView.showLoading()
boxOfficeListView.boxOfficeListDelegate = self
boxOfficeListView.delegate = self
boxOfficeListView.dataSource = dataSource
view = boxOfficeListView
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비슷한 역할을 하는 것들끼리 묶어두셨네요! 좋은 방법인 것 같습니다.


func setupBoxOfficeData() {
movieManager.fetchBoxOfficeResultData(date: Date.movieDateToString) { result in
switch result {
case .success(let success):
self.reloadCollectionListData(result: success)
case .failure(let failure):
print("fetchBoxOfficeResultData 실패: \(failure)")
Task {
do {
let result = try await movieManager.fetchBoxOfficeResultData(date: Date.movieDateToString)
self.reloadCollectionListData(result: result)
LoadingIndicatorView.hideLoading()
} catch {
print(error.localizedDescription)
}
}
}
Expand All @@ -60,27 +66,26 @@ private extension BoxOfficeViewController {
}

func updateBoxOfficeList() {
movieManager.fetchBoxOfficeResultData(date: Date.movieDateToString) { [weak self] result in
switch result {
case .success(let result):
DispatchQueue.main.async {
self?.applyBoxOfficeList(result: result)
guard
let date = result.showRange.toDateFromRange()
else {
return
}
self?.configureNavigation(date: date)
Task {
do {
let result = try await self.movieManager.fetchBoxOfficeResultData(
date: Date.movieDateToString
)
self.applyBoxOfficeList(result: result)
guard
let date = result.showRange.toDateFromRange()
else {
return
}
case .failure(let error):
self.configureNavigation(date: date)
} catch {
print(error.localizedDescription)
}
}
}

func reloadCollectionListData(result: BoxOfficeResult) {
DispatchQueue.main.async {
self.boxOfficeListView.indicatorView.stopAnimating()
self.configureNavigation(date: Date.yesterday)
self.applyBoxOfficeList(result: result)
self.boxOfficeListView.isScrollEnabled = true
Expand All @@ -90,7 +95,17 @@ private extension BoxOfficeViewController {

extension BoxOfficeViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.navigationController?.popViewController(animated: true)
guard
let data = movieManager.setupBoxOfficeDetailData(for: indexPath.row)
else {
return
}
let detailViewController = BoxOfficeDetailViewController(
movieName: data.movieName,
movieCode: data.movieCode,
movieManager: movieManager
)
self.navigationController?.pushViewController(detailViewController, animated: true)
}
}

Expand Down
15 changes: 13 additions & 2 deletions BoxOffice/Extension/Bundle+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import Foundation

extension Bundle {
var apiKey: String {
guard
var movieApiKey: String {
guard
let file = self.path(forResource: "Private", ofType: "plist"),
let resource = NSDictionary(contentsOfFile: file),
let key = resource["API_KEY"] as? String
Expand All @@ -18,4 +18,15 @@ extension Bundle {
}
return key
}

var kakaoApiKey: String {
guard
let file = self.path(forResource: "Private", ofType: "plist"),
let resource = NSDictionary(contentsOfFile: file),
let key = resource["Kakao_API_KEY"] as? String
else {
return ""
}
return key
}
}
19 changes: 15 additions & 4 deletions BoxOffice/Extension/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ import Foundation

extension String {
func toDateFromRange() -> Date? {
guard let result = self.split(separator: "~").last else { return nil }
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
return dateFormatter.date(from: Self(result))
guard
let result = self.split(separator: "~").last
else {
return nil
}
return Date.movieDateFormatter.date(from: Self(result))
}

var makeDateFormat: String {
guard
let date = Date.movieDateFormatter.date(from: self)
else {
return "-"
}
return Date.titleDateFormatter.string(from: date)
}
}
12 changes: 2 additions & 10 deletions BoxOffice/Extension/URLSession+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,7 @@
import Foundation

extension URLSession: URLSessionProtocol {
func dataTask(
with url: URL,
completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
) -> URLSessionDataTaskProtocol {
return dataTask(
with: url,
completionHandler: completionHandler
) as URLSessionDataTask
func requestData(with request: URLRequest) async throws -> (Data, URLResponse) {
return try await data(for: request)
}
}

extension URLSessionDataTask: URLSessionDataTaskProtocol {}
28 changes: 28 additions & 0 deletions BoxOffice/Model/Movie/Image/Document.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Document.swift
// BoxOffice
//
// Created by 강창현 on 3/8/24.
//

struct Document: Codable {
let collection: String
let thumbnailURL: String
let imageURL: String
let width: Int
let height: Int
let displaySiteName: String
let docURL: String
let datetime: String

enum CodingKeys: String, CodingKey {
case collection
case thumbnailURL = "thumbnail_url"
case imageURL = "image_url"
case width
case height
case displaySiteName = "display_sitename"
case docURL = "doc_url"
case datetime
}
}
18 changes: 18 additions & 0 deletions BoxOffice/Model/Movie/Image/Meta.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Meta.swift
// BoxOffice
//
// Created by 강창현 on 3/8/24.
//

struct Meta: Codable {
let totalCount: Int
let pageableCount: Int
let isEnd: Bool

enum CodingKeys: String, CodingKey {
case isEnd = "is_end"
case pageableCount = "pageable_count"
case totalCount = "total_count"
}
}
11 changes: 11 additions & 0 deletions BoxOffice/Model/Movie/Image/MovieImage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// MovieImage.swift
// BoxOffice
//
// Created by 강창현 on 3/8/24.
//

struct MovieImage: Codable {
let meta: Meta
let documents: [Document]
}
Loading