Skip to content

yoruck2/Popcorn

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Popcorn

TMDB API๋ฅผ ํ™œ์šฉํ•œ ์˜ํ™”, ์‹œ๋ฆฌ์ฆˆ ์—ด๋žŒํ•  ์ˆ˜ ์žˆ๋Š” ์•ฑ

ํŠธ๋ Œ๋“œ ๊ฒ€์ƒ‰ ์ฐœ ์ƒ์„ธ

ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ

  • ์ธ์›: 3์ธ
  • ๊ธฐ๊ฐ„: 24.10.08 ~ 24.10.14 (6์ผ)
  • ์ตœ์†Œ ๋ฒ„์ „: iOS 15.0+

ํ˜‘์—…๊ด€๋ฆฌ

  • ๋ธŒ๋žœ์น˜ ์ „๋žต: Github Flow + develop ๋ธŒ๋žœ์น˜๋ฅผ ์ถ”๊ฐ€ํ•œ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ

    • ๊ฐ ๊ธฐ๋Šฅ์€ ๋ณ„๋„์˜ feature ๋ธŒ๋žœ์น˜์—์„œ ๊ฐœ๋ฐœ๋˜๊ณ , develop ๋ธŒ๋žœ์น˜์—์„œ ํ†ตํ•ฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ
    • ์ด๋กœ์จ ์„œ๋กœ์˜ ์ž‘์—…์— ์˜ํ–ฅ๋ฐ›์ง€ ์•Š๊ณ  ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋ฉฐ, ์ถฉ๋Œ ์ตœ์†Œํ™” ๊ฐ€๋Šฅ
    • ์•ˆ์ •์ ์ธ main ๋ธŒ๋žœ์น˜ ์œ ์ง€: ๊ฒ€์ฆ๋œ ์ฝ”๋“œ๋งŒ main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ ๋ฐ ํ•ญ์ƒ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ ์œ ์ง€
  • ์ปจ๋ฒค์…˜

    1. PR Template PR Template ํ†ตํ•ด ์ผ๊ด€๋œ PR ํ˜•์‹ ์œ ์ง€
    2. ์ปค๋ฐ‹ ์ปจ๋ฒค์…˜ ๋„๋ฆฌ ์•Œ๋ ค์ง„ Karma ์ปจ๋ฒค์…˜์„ ์ฑ„ํƒ
    3. ์ฝ”๋“œ ์ปจ๋ฒค์…˜ swiftLint ๋ฅผ ํ™œ์šฉํ•ด ํ•ฉ์˜๋œ ์ฝ”๋“œ ์ปจ๋ฒค์…˜ ๊ณต์œ 
  • ์ž‘์—… ๋ถ„๋ฐฐ

    1. ์‚ฌ์šฉํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ๋ฐ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ตฌ์กฐ ์„ค์ • ๋ฐ ํด๋”๋ง ์ž‘์—…
    2. ๊ณตํ†ต ๊ธฐ๋Šฅ - Network, DB, ViewComponent ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ์˜์กด์„ฑ์ด ์กด์žฌํ•˜๊ฑฐ๋‚˜, ์žฌ์‚ฌ์šฉ ๋˜๋Š” ๊ธฐ๋Šฅ ๋จผ์ € ๊ตฌ์„ฑ
    3. ๊ตฌ์„ฑ์›๋ณ„ ๋‹ด๋‹น์—…๋ฌด ๋ถ„๋ฐฐ
      • ๊น€์„ฑ๋ฏผ: DB ์Šคํ‚ค๋งˆ ๋ฐ Repository ๊ตฌ์„ฑ
      • ์ด์Šนํ˜„: ๋„คํŠธ์›Œํฌ ๋ชจ๋“ˆํ™” ๋ฐ ์˜ค๋ฅ˜์ฒ˜๋ฆฌ
      • ํ™์ •๋ฏผ: ์ปค์Šคํ…€๋ทฐ ๋ฐ ๊ณตํ†ต UI ์ž‘์—…
    4. ์ดํ›„ ์ž‘์—…์€ ViewController ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ์ง„ํ–‰
  • PR Flow

    1. PR ์š”์ฒญ
    2. ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ ์Šน์ธ
    3. PR ์Šน์ธ ๋ฆฌ๋ทฐ๊ฐ€ ์™„๋ฃŒ๋œ PR์€ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ๋ฉ๋‹ˆ๋‹ค.
  • Conflict ํ•ด๊ฒฐ ๊ณผ์ •

    • ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ๋ณ€๊ฒฝ ์ตœ์†Œํ™”๋ฅผ ์œ„ํ•ด ์ƒˆ๋กœ์šด ํŒŒ์ผ ์ถ”๊ฐ€๋‚˜ ์„ค์ • ๋ณ€๊ฒฝ ์‹œ ํŒ€์›๋“ค๊ณผ ์‚ฌ์ „ ํ˜‘์˜ ์ง„ํ–‰
    • ๋จธ์ง€ ํƒ€์ž„ ์ง„ํ–‰ ํ•„์š” ์‹œ์ ์— Merge time์„ ์ง€์ •ํ•˜์—ฌ ํŒ€์›๋“ค์ด ๋ชจ์—ฌ ๋ณ‘ํ•ฉ ์ž‘์—…์„ ํ•จ๊ป˜ ์ˆ˜ํ–‰

    ์ ๊ทน์ ์ธ ์†Œํ†ต์„ ํ†ตํ•œ ์‹ค์‹œ๊ฐ„ ์ถฉ๋Œ ํ•ด๊ฒฐ ๋ฐ ๋ณ‘ํ•ฉ ๊ณผ์ •์—์„œ์˜ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ

    • ์„ ํ–‰๊ณผ ํ›„ํ–‰ ์ž‘์—… ๊ณ ๋ ค ์„œ๋กœ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ์„ ํ–‰ ์ž‘์—…๊ณผ ํ›„ํ–‰ ์ž‘์—…์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ณ‘ํ•ฉ ์ˆœ์„œ ๊ฒฐ์ •

    ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ด๋‚˜ ๊ณตํ†ต ๋ชจ๋“ˆ์€ ์šฐ์„ ์ ์œผ๋กœ ๋ณ‘ํ•ฉํ•˜๊ณ  ์ด์— ์˜์กดํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค์„ ๊ทธ ์ดํ›„์— ๋ณ‘ํ•ฉํ•˜์—ฌ ์ถฉ๋Œ ๋ฐฉ์ง€

๊ธฐ์ˆ  ์Šคํƒ

๋ถ„์•ผ ๊ธฐ์ˆ  ์Šคํƒ
๐Ÿ›๏ธ Architecture MVVM
+ Input & Output ํŒจํ„ด
โ™ป๏ธ ๋น„๋™๊ธฐ RxSwift
๐Ÿ“ก ๋„คํŠธ์›Œํ‚น Alamofire
+ Router ํŒจํ„ด
๐Ÿ“ฆ DB RealmSwift
+ Repository ํŒจํ„ด
๐ŸŽจ UI UIKit
SnapKit
Kingfisher
๐Ÿ“ Code Convention SwiftLint
๐ŸŽธ ๊ธฐํƒ€ WebKit
Then

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  • ์ธ๊ธฐ์˜ํ™”&์‹œ๋ฆฌ์ฆˆ ์‚ดํŽด๋ณด๊ธฐ
    • RxDataSources๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์ค‘ ์„น์…˜ ์ปฌ๋ ‰์…˜๋ทฐ ๊ตฌ์„ฑ
  • ์˜ํ™”&์‹œ๋ฆฌ์ฆˆ ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰ ๋ฐ ์ถ”์ฒœ ์ปจํ…์ธ  ์ œ๊ณต
    • RxSwift์˜ ์˜คํผ๋ ˆ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ API ๊ณผํ˜ธ์ถœ ๋ฐฉ์ง€
  • ์˜ํ™”&์‹œ๋ฆฌ์ฆˆ ์ƒ์„ธ์ •๋ณด ์ œ๊ณต ๋ฐ ๋น„์Šทํ•œ ์ปจํ…์ธ  ์ถ”์ฒœ
  • ์˜ํ™”&์‹œ๋ฆฌ์ฆˆ ์˜ˆ๊ณ ํŽธ ์žฌ์ƒ
    • WebKit์„ ์‚ฌ์šฉํ•œ ์œ ํˆฌ๋ธŒ ํ”Œ๋ ˆ์ด์–ด ์žฌ์ƒ
  • ์˜ํ™”&์‹œ๋ฆฌ์ฆˆ ์ฆ๊ฒจ์ฐพ๊ธฐ
    • Realm Database + FileManager ๋กœ ๋กœ์ปฌ์— ์˜ํ™”์ •๋ณด ์ €์žฅ

์ฃผ์š” ๊ธฐ์ˆ 

  • DTO๋ฅผ ํ†ตํ•œ API ๋ชจ๋ธ๊ณผ Presentation ๋ชจ๋ธ์˜ ๋ถ„๋ฆฌ
  • RxDataSources์™€ CompositionalLayout์„ ํ™œ์šฉํ•ด ๋ฉ€ํ‹ฐ ์„น์…˜ ์ปฌ๋ ‰์…˜ ๋ทฐ ๋Œ€์‘
  • Realm Database ์ ‘๊ทผ ์‹œ Repository ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ˜ํ…์ธ  ์ •๋ณด ๋กœ์ปฌ ์ €์žฅ
  • ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€ ๋กœ์ปฌ ์ €์žฅ์„ ์œ„ํ•ด FileManager ์‚ฌ์šฉ
  • jpegData ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•œ ์ด๋ฏธ์ง€ ์••์ถ• ๋ฐ ์šฉ๋Ÿ‰ ์ตœ์ ํ™”
  • RxSwift์˜ debounce์™€ distinctUntilChanged๋ฅผ ํ™œ์šฉํ•œ API ๊ณผํ˜ธ์ถœ ๋ฐฉ์ง€
  • ํƒ€์ž…์œผ๋กœ์จ์˜ protocol๊ณผ extension์„ ์‚ฌ์šฉํ•œ UIView์˜ identifier ๊ด€๋ฆฌ
  • Protocol์„ ์‚ฌ์šฉํ•ด ViewModel์˜ Input-Output ๊ตฌ์กฐํ™”
  • String Catalog์™€ String Extension์„ ํ™œ์šฉํ•œ ๋‹ค๊ตญ์–ด ๋Œ€์‘ (์˜์–ด, ํ•œ๊ตญ์–ด)
  • RxNotification์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‹ค์‹œ๊ฐ„ ๊ฐ์ง€ ๋ฐ UI ์—…๋ฐ์ดํŠธ
  • Single ํƒ€์ž…๊ณผ ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•œ ๋„คํŠธ์›Œํฌ ์ถ”์ƒํ™” ๋ฐ ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ

ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

RxDataSources๋กœ ์—ฌ๋Ÿฌ ์„น์…˜์„ ๋Œ€์‘ํ•˜๋Š” ๋ฌธ์ œ

  • sectionProvider๋ฅผ ํ†ตํ•ด sectionIndex์— ๋”ฐ๋ฅธ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ
  • AnimatableSectionModel ํƒ€์ž…์˜ ์„น์…˜ ๋ชจ๋ธ ์ƒ์„ฑ
  • RxCollectionViewSectionedAnimatedDataSource๋ฅผ ๊ตฌ์„ฑํ•ด Data Binding
  • "At least 1 subitem is required for a group" ์—๋Ÿฌ ๋ฐœ์ƒ
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [])
  • ์…€ ์—†์ด ํ—ค๋”๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด subitems๊ฐ€ ์—†๋Š” NSCollectionLayoutGroup์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋จ
  • heightDimension์„ 0.01๋กœ ์„ค์ •ํ•œ NSCollectionLayoutItem์„ subitems์— ์ถ”๊ฐ€ํ•ด์คŒ์œผ๋กœ์จ ํ•ด๊ฒฐ

ํšŒ๊ณ 

ํ˜‘์—…์—์„œ์˜ ์•„์‰ฌ์›€

  1. ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์˜์‚ฌ์†Œํ†ต ๋ถ€์žฌ ์‚ฌ์ „์— ๊ณตํ†ตํ™”๋ฉด์— ๋Œ€ํ•œ ํ™”๋ฉด์ „ํ™˜์„ ํ†ต์ผํ•˜์ง€ ์•Š์•„ ํ™”๋ฉด์ด ๋˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ. ํ™”๋ฉด์ „ํ™˜ ๊ฐ™์€ ๋ถ€๋ถ„๋“ค๋„ ์‚ฌ์ „ํ•ฉ์˜๋ฅผ ํ†ตํ•ด ์ˆ˜์ •์‚ฌํ•ญ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊นจ๋‹ฌ์Œ
  2. Realm ๋ชจ๋ธ์— ๋Œ€ํ•œ ๊ณตํ†ตํ•ฉ์˜ ๋ถ€์กฑ ํ”„๋กœ์ ํŠธ ์ค‘์— Realm ๋ชจ๋ธ์— ๋ณ€๊ฒฝ์ ์ด ๋ฐœ์ƒ. ๊ด€๋ จ๋œ ๋กœ์ง์„ ๋ชจ๋‘ ์ˆ˜์ •ํ•˜๊ณ  Conflict๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ ์ดˆ๋ฐ˜ ๋ชจ๋ธ ์„ค๊ณ„์˜ ์ค‘์š”์„ฑ์„ ๊นจ๋‹ฌ์Œ

ํ”„๋กœ์ ํŠธ์—์„œ์˜ ์•„์‰ฌ์›€

  • FileManager ์‚ฌ์šฉ ์‹œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ๋ถ€๋ถ„์˜ ํ•ธ๋“ค๋ง์ด ๋˜์–ด์žˆ์ง€ ์•Š์•„ ์•„์‰ฌ์›€. ์ถ”ํ›„ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์— ๋Œ€ํ•œ ๋ถ€๋ถ„์ด ๊ฐœ์„ ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์Œ

About

๐Ÿฟ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%