Skip to content
Open
Show file tree
Hide file tree
Changes from 88 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
6d5f518
config: 깃이그노어 추가
suojae Feb 13, 2024
01b3890
feat: BoxOfficeExample Json파일 추가
suojae Feb 14, 2024
2f96fe3
feat: BoxOfficeData Json 파싱을 위한 모델 타입 구현
hemil0102 Feb 14, 2024
ecc306e
feat: UnitTest 추가
suojae Feb 14, 2024
53a0c23
feat: jsonParsingError 에러 처리 enum 타입 구현
hemil0102 Feb 14, 2024
e4a9f20
feat: Json 디코딩을 위한JsonDecoder() 타입 구현
hemil0102 Feb 14, 2024
977ca6d
feat: BoxOfficeSample.json 파싱 확인을 위한 뷰컨트롤러 기능 구현
hemil0102 Feb 14, 2024
40efade
refactor: 안쓰는 메서드 삭제
suojae Feb 14, 2024
d6af27e
refactor: JsoDecoder 리팩토링
suojae Feb 14, 2024
fdf8d7c
refactor: loadData 에러처리 메서드 안으로 들여옴
suojae Feb 14, 2024
02bd755
test: JsonDecoder 파싱 데이터 단위의 Unit Test 구현
hemil0102 Feb 14, 2024
73121b0
test: 파일이름,타입이름 유닛테스트 메서드 추가
suojae Feb 14, 2024
6f7cb09
test: loadData의 에러처리 nil값으로 확인
suojae Feb 14, 2024
b445c48
chore: 안쓰는 에러케이스 삭제
suojae Feb 14, 2024
67a73db
refactor: 에러 처리 컨벤션에 맞게 수정
suojae Feb 14, 2024
b2d8792
refactor: CodingKeys 열거형 private 접근 수준 적용
hemil0102 Feb 16, 2024
e2a557f
refactor: 모델 설계struct Codable 프로토콜을 용도에 맞게 Decodable로 변경
hemil0102 Feb 16, 2024
eafdd5c
refactor: ViewControlloer final 키워드 적용 및 네이밍 수정
hemil0102 Feb 16, 2024
a618128
config: 스토리보드 제거 및 폴더링
suojae Feb 16, 2024
b412f62
feat: .gitignore 에 Private 폴더 추가
suojae Feb 16, 2024
3fbc5e3
feat: KeyEnvironmentHandler 추가
suojae Feb 16, 2024
eb6c77b
config: step2 네트워크 구현 폴더링
hemil0102 Feb 22, 2024
46b0b2d
chore: DTO로 네이밍 수정
suojae Feb 22, 2024
2ec57b3
feat: Network Error 타입 및 NetworkResponse 모델 구현
hemil0102 Feb 22, 2024
feaced2
feat: Network Error 타입 및 NetworkResponse 모델 구현
hemil0102 Feb 22, 2024
bc334f5
chores: 충돌 방지용 파일 형성
hemil0102 Feb 22, 2024
e6bb32e
feat: requestProvider 추가
suojae Feb 22, 2024
e882527
feat: URLSession 생성 및 task 수행을 위한 sessionProvider 구현
hemil0102 Feb 22, 2024
3a05091
chores: 오타 수정
hemil0102 Feb 22, 2024
ae9e940
feat: BaseURLManager 추가
suojae Feb 22, 2024
f7cbba9
feat: URLProvider 추가
suojae Feb 22, 2024
506e9ba
chore: Request 수정
suojae Feb 22, 2024
a955aa4
chore: 빈파일 네이밍 및 안쓰는 코드 주석처리 및 제거
suojae Feb 22, 2024
091e3ed
chore: 중복파일 제거 및 BaseURL 넣어주기
suojae Feb 22, 2024
9566e5d
feat: 디코더 추가
suojae Feb 23, 2024
e373045
feat: movieRepository 타입 구현
hemil0102 Feb 23, 2024
bb249fc
chores: 오타 수정
hemil0102 Feb 23, 2024
cff01c0
feat: Entity 및 DTO에서 Entity로 맵핑 기능 추가
suojae Feb 23, 2024
633d111
feat: Domain Error 타입 구현
hemil0102 Feb 23, 2024
a97b9a0
feat: UseCase 추가
suojae Feb 23, 2024
0c97abe
feat: HTTPMethod 관리 객체 추가
suojae Feb 23, 2024
4789830
chore: 오타 및 네이밍 수정
suojae Feb 23, 2024
45af001
feat: 의존성 관리 객체 추가
suojae Feb 23, 2024
1b1f3af
test: 테스트를 위한 로그 코드 작성
suojae Feb 23, 2024
a1ac95d
chore: 에러 수정
suojae Feb 23, 2024
b70e580
feat: Test용 Stub 데이터 구현
hemil0102 Feb 23, 2024
1cfb86d
feat: MockURLProtocol 타입 구현
hemil0102 Feb 23, 2024
2c9079a
feat: DetailMovieInfoDTO 타입 생성
hemil0102 Feb 23, 2024
c561df7
feat: DateExtension 추가
suojae Feb 23, 2024
e484df7
feat: MovieDetailInfo 엔티티 추가
suojae Feb 23, 2024
5545f25
chore: 안쓰고 있는 메서드 제거
suojae Feb 23, 2024
f6ac24c
refacot: URLProvider Query 재사용성 개선
hemil0102 Feb 23, 2024
555ae74
feat: 영화 개별 상세 조회관련 기능 구현
hemil0102 Feb 23, 2024
c4015cc
test: 세션 유닛테스트 추가
suojae Feb 23, 2024
9780552
refacotor: 컨벤션 및 접근 제어 수정
hemil0102 Feb 23, 2024
871e3c8
chore: 미사용 파일 삭제
suojae Feb 23, 2024
9ffabf3
refactor: BaseURLType 열거형 Hasable 프로토콜 삭제
hemil0102 Feb 28, 2024
ebe63a5
refactor: APIKeyable 프로토콜 이름 APIKey로 수정
hemil0102 Feb 28, 2024
90f491c
refactor: RequestProvidable extension 불필요한 코드 삭제
hemil0102 Feb 28, 2024
ceb6e48
refactor: makeURLRequest() 메서드 파라미터 타입 URLProvider을 URLProvidable로 변경
hemil0102 Feb 28, 2024
0caedf6
refactor: cofigureURL() guard let 에러 처리 방식 변경
hemil0102 Feb 28, 2024
37fc1b7
Step2 merge
suojae Mar 1, 2024
cafce2e
refactor: step2 리팩토링
suojae Mar 7, 2024
a3a501a
2
suojae Mar 7, 2024
b8b1835
feat: 도메인 Entity 모델 수정 및 프레젠테이션 DisplayModel 생성
hemil0102 Mar 8, 2024
edf367f
feat: 박스오피스 Cell 추가
suojae Mar 8, 2024
ca65fec
feat: BoxOfficeCollectionView 생성
hemil0102 Mar 8, 2024
95878ee
feat: 박스오피스 디스플레이 모델에 placeholder추가
suojae Mar 8, 2024
efdf9d2
feat: raceCondition 방지를 위한 SynchronizedLock 프로퍼티 래퍼 추가
suojae Mar 8, 2024
6486599
feat: Alert창기능 추가
suojae Mar 8, 2024
630ea9d
feat: numberFormatter 기능 추가
suojae Mar 8, 2024
d1d664e
feat: BoxOfficeViewController 내에 ModernCollectionView 구현
hemil0102 Mar 8, 2024
9fbfc05
refactor: 일부 함수명 개선
hemil0102 Mar 8, 2024
4150155
refactor: BoxOfficeViewController 리팩토링
suojae Mar 8, 2024
4f1d498
refactor: 컨벤션 일관성 개선 및 접근제어 수준 반영
hemil0102 Mar 8, 2024
b780823
refactor: 폴더 구조 및 일부 파일명 변경
hemil0102 Mar 8, 2024
098dba2
chore: alert창 메세지에 에러 삽입
suojae Mar 8, 2024
8879a75
chore: 접근제어 수정
suojae Mar 8, 2024
6400fbb
refactor: JsonDecoder 의존성 주입 추가
hemil0102 Mar 11, 2024
330f0f4
refactor: URL관리 객체 리팩토링
suojae Mar 11, 2024
7d51d1b
refactor: URLRequest 분리
hemil0102 Mar 11, 2024
70488b1
refactor: 의존성 관리객체 리팩토링
suojae Mar 11, 2024
1861366
refactor: 메서드명 개선
hemil0102 Mar 11, 2024
5a89206
chore: 줄간격, 접근제어 등 잔잔바리 수정
suojae Mar 11, 2024
573f503
chore: 변수명 변경
suojae Mar 11, 2024
ab8fc39
refactor: 줄 간격 수정 및 오타 수정
hemil0102 Mar 12, 2024
91cd1ea
docs: 프로젝트 구조 파악 향상을 위한 폴더링 구조 변경
hemil0102 Mar 12, 2024
755992e
docs: 가독성 향상을 위한 파일 위치 변경
hemil0102 Mar 12, 2024
e913271
refactor: 범용성있는 뷰컨팩토리로 수정
suojae Mar 13, 2024
795a82a
chore: 네이밍 수정
suojae Mar 13, 2024
ea5a624
chore: 잔잔바리 삭제
suojae Mar 13, 2024
bf1468c
refactor: 코드 가독성 향상을 위한 스택뷰 설정 반복문 적용
hemil0102 Mar 18, 2024
05b38f2
refactor: applySnapshot()을 백그라운드큐에서 동작하도록 일관성 유지 개선
hemil0102 Mar 18, 2024
dab8c27
refactor: 불필요한 뷰 제거
suojae Mar 18, 2024
002e961
chore: static 제거
suojae Mar 18, 2024
636d994
refactor: NetworkManager 삭제 및 RequestBuilder 구조 변경
hemil0102 Mar 18, 2024
a38b6e0
refactor: Repository - UseCase 사이 데이터 Mapper 구현
hemil0102 Mar 20, 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
135 changes: 135 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Created by https://www.toptal.com/developers/gitignore/api/macos,swift,xcode
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,swift,xcode

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### Swift ###
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
Private/
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm

.build/

# CocoaPods
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
# Pods/
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build/

# Accio dependency management
Dependencies/
.accio/

# fastlane
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/

### Xcode ###

## Xcode 8 and earlier

### Xcode Patch ###
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcodeproj/project.xcworkspace/
!*.xcworkspace/contents.xcworkspacedata
/*.gcno
**/xcshareddata/WorkspaceSettings.xcsettings

# End of https://www.toptal.com/developers/gitignore/api/macos,swift,xcode
538 changes: 507 additions & 31 deletions BoxOffice.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions BoxOffice.xcodeproj/xcshareddata/xcschemes/BoxOffice.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "63DF20EA2970E1A0005DF7D1"
BuildableName = "BoxOffice.app"
BlueprintName = "BoxOffice"
ReferencedContainer = "container:BoxOffice.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08DCFEDB2B7C59D7002E22EA"
BuildableName = "BoxOfficeUnitTests.xctest"
BlueprintName = "BoxOfficeUnitTests"
ReferencedContainer = "container:BoxOffice.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "63DF20EA2970E1A0005DF7D1"
BuildableName = "BoxOffice.app"
BlueprintName = "BoxOffice"
ReferencedContainer = "container:BoxOffice.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "63DF20EA2970E1A0005DF7D1"
BuildableName = "BoxOffice.app"
BlueprintName = "BoxOffice"
ReferencedContainer = "container:BoxOffice.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
22 changes: 22 additions & 0 deletions BoxOffice/App/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}

/// 배포/디버깅 환경에 따라 키값 글로벌 선언
var ENV: APIKey {

Choose a reason for hiding this comment

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

현재 debug와 production이 나눠질 필요가 없는 것으로 보여요.
삭제되어야할 부분으로 보입니다. 삭제한다면
ENV는 어떻게 관리 되는 것이 좋을까요?

Copy link
Author

Choose a reason for hiding this comment

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

debug와 production이 나눌필요가 없어 get으로 받는 프로토콜만 남겼습니다!
해당 파일은 깃이그노어로 숨겨줄 수 있습니다! (학습용이라 판단하여 따로 숨김처리는 하지 않았습니다)

#if DEBUG
return DebugEnvironment()
#else
return ProdEnvironment()
#endif
}
29 changes: 29 additions & 0 deletions BoxOffice/App/DependencyEnvironment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

import Foundation

final class DependencyEnvironment {
/// 디코더 설정 셋팅 예시
private let jsonDecoder: JSONDecoder = {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .iso8601
return jsonDecoder
}()

private lazy var decodeProvider: JsonDecodeProtocol = JsonDecoder(jsonDecoder: jsonDecoder)

private lazy var sessionProvider: SessionProvidable = SessionProvider()

Choose a reason for hiding this comment

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

lazy는 꼭 사용되어야 하는 부분에서만 사용되면 좋을 것 같아요!
lazy로 설계한 이유에 대해서 말씀해주세요

Copy link
Author

@suojae suojae Mar 13, 2024

Choose a reason for hiding this comment

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

Lazy 사용 장점

1. 초기화 작업 단축
앱이 시작할 때 필요하지 않은 초기화 작업을 하지않아 앱시작 시간을 최적화합니다.

2. 초기화 순서문제 예방
A를 주입받는 B객체는 A 이후에 초기화해야됩니다. lazy는 필요한 시점에 초기화함으로써 이와같은 순서문제를 예방할 수 있습니다.

Lazy 사용으로 인한 단점

lazy는 thread safe하지 않다
lazy 프로퍼티는 스레드안전성을 보장하지 못하기 때문에 초기화 시점에서 동시접근시 문제가 생길 수 있습니다.


lazy 사용이유

현재 객체 생성은 팩토리 메서드로 만들어지며 별다른 비동기 실행이 이루어지지 않고 있습니다.
"초기화 순서문제 예방"이라는 추가적 이점을 얻을 수 있기 때문에 lazy를 통해 생성해주고 있습니다.


private lazy var requestBuidler: RequestBuilderProtocol = RequestBuilder()

private lazy var networkManager: NetworkManagerProtocol = NetworkManager(sessionProvider: sessionProvider, decoder: decodeProvider)

private lazy var movieRepository: MovieRepositoryProtocol = MovieRepository(networkManager: networkManager, requestBuilder: requestBuidler)

private lazy var boxOfficeUseCase: BoxOfficeUseCaseProtocol = BoxOfficeUseCase(moviesRepository: movieRepository)
}

extension DependencyEnvironment: ViewControllerFactoryProtocol {
func makeBoxOfficeCollectionViewController() -> BoxOfficeViewController {
BoxOfficeViewController(boxOfficeUseCase: boxOfficeUseCase)
}
}
18 changes: 18 additions & 0 deletions BoxOffice/App/SceneDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
private let viewControllerFactory:ViewControllerFactoryProtocol = DependencyEnvironment()

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

guard let windowScene = (scene as? UIWindowScene) else { return }

let mainViewController = UINavigationController(rootViewController: viewControllerFactory.makeBoxOfficeCollectionViewController())

window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.rootViewController = mainViewController
}
}
4 changes: 4 additions & 0 deletions BoxOffice/App/ViewControllerFactoryProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

protocol ViewControllerFactoryProtocol {

Choose a reason for hiding this comment

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

Protocol을 통해 범용성 있는 FactoryProtocol을 만들었지만
make를 통해 만들어지는 ViewController의 이름이 그대로 들어있게 되어서 해당 protocol은
범용성이 많이 떨어지게 느껴져요 범용성 있게 수정하면 좋을 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

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

수정커밋: e913271

프로토콜 메서드의 리턴타입을 UIViewController로 바꾸어 케이스별로 뷰컨을 만들어낼 수 있도록 범용성 확장했습니다!

func makeBoxOfficeCollectionViewController() -> BoxOfficeViewController
}
36 changes: 0 additions & 36 deletions BoxOffice/AppDelegate.swift

This file was deleted.

24 changes: 0 additions & 24 deletions BoxOffice/Base.lproj/Main.storyboard

This file was deleted.

20 changes: 20 additions & 0 deletions BoxOffice/Common/DateExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import Foundation

extension Date {
static var yesterday: Date { return Date().dayBefore }

var dayBefore: Date {
return Calendar.current.date(byAdding: .day, value: -1, to: noon)!
}

var noon: Date {
return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}

func formattedDate(withFormat format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
Loading