๐Ÿ’› Welcome to BAPPY's iOS APP ๐Ÿ’›





Logo




๐ŸŒผ Project

Create the new shared experience with new freinds!

Join hangouts and make friends wherever you are!

Project Duration: 2022.05.10 ~

App Release : Soon





๐ŸŒผ Architecture

1. UIKit + RxSwift๋ฅผ ์ด์šฉํ•œ MVVM ๋””์ž์ธ ํŒจํ„ด

View๋ฅผ ๋‹ด๋‹นํ•˜๋Š” UIViewController๋‚˜ UIView์— ViewModelType ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ViewModel์ด 1:1 ๋Œ€์‘ํ•˜๋Š” ๊ตฌ์กฐ

View์— ์žˆ๋Š” bind() ํ•จ์ˆ˜์—์„œ View์—์„œ ๋ฐœ์ƒํ•œ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋Š” ViewModel์˜ Input์— Bindingํ•˜๊ณ  ์ž…๋ ฅ ๋ฐ›์€ ์ด๋ฒคํŠธ๋ฅผ ViewModel์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ViewModel์˜ Output์„ ๋‹ค์‹œ View์— Bindingํ•˜์—ฌ ์œ ์ €์—๊ฒŒ ๋ณด์—ฌ์งˆ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œ

protocol ViewModelType {

    associatedtype Dependency
    associatedtype Input
    associatedtype Output
  
    var dependency: Dependency { get }
    var disposeBag: DisposeBag { get set }

    var input: Input { get }
    var output: Output { get }

    init(dependency: Dependency)
}
class ViewModel: ViewModelType {

    struct Dependency {}
    struct Input {}
    struct Output {}
    
    let dependency: Dependency
    var disposeBag = DisposeBag()
    let input: Input
    let output: Output
    
    init(dependency: Dependency) {
        self.dependency = dependency
        
        // MARK: Streams
        /*
        input & output ๋“ฑ ๋กœ์ง์„ ์œ„ํ•ด ํ•„์š”ํ•œ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
        */
        
        // MARK: Input & Output
        self.input = Input()
        self.output = Output()
        
        // MARK: Binding
        /*
        ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
        */
    }
}
class ViewController: UIViewController {

    // MARK: Properties
    private let viewModel: ViewModel
    private let disposeBag = DisposeBag()
    
    // MARK: Lifecycle
    init(viewModel: ViewModel) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
        
        bind()
    }
    
    // MARK: Bind
    private func bind() {
        /*
        1. View์—์„œ ๋ฐœ์ƒํ•˜๋Š” Event๋ฅผ ViewModel์˜ Input์— ๋ฐ”์ธ๋”ฉ
        2. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ํ›„ ์œ ์ €์—๊ฒŒ ๋ณด์—ฌ์งˆ ๋ฐ์ดํ„ฐ๋ฅผ ViewModel์˜ Output์—์„œ UI Component์— ๋ฐ”์ธ๋”ฉ
        */
    }
}



2. ์ „์ฒด์ ์ธ Layer ์„ค๊ณ„

Layer Components Description
Presentation* View + ViewModel MVVM
Domain* ViewModel + Repository(Interface) + Entity Business Logic
Data* Repository(Implementation) + Network + DB Data Repository

์•ฑ์˜ ์ „๋ฐ˜์ ์ธ Layer๋Š” "Clean Architecture + MVVM"๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์„ค๊ณ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ํ•œ ์ž๋ฃŒ์—์„œ๋Š” ViewModel๊ณผ UseCase๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ
ViewModel์€ View๋ฅผ ๊ทธ๋ฆฌ๋Š” Presentation ์˜์—ญ์—
UseCase๋Š” ๋น„์ฆˆ๋‹ˆ์Šค๋กœ์ง๊ณผ ๊ด€๋ จ๋œ Domain์˜์—ญ์— ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ณ  ์žˆ์ง€๋งŒ,

์ด ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ViewModel์ด ๋‘ ๋กœ์ง์„ ๋ชจ๋‘ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.



3. ๋„คํŠธ์›Œํฌ Layer ์„ค๊ณ„

๋„คํŠธ์›Œํฌ ๊ด€๋ จ Layer๋Š” "Testableํ•œ URLSession ์„ค๊ณ„"๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์„ค๊ณ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋†’์€ ๋นˆ๋„๋กœ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋„คํŠธ์›Œํฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์ด ์ข‹์€ ๋„คํŠธ์›Œํฌ Layer๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, API ํ˜ธ์ถœ์€ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ๋†’์—ฌ Unit Test๋ฅผ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— URLSession์ด ์•„๋‹Œ URLSessionable์ด๋ผ๋Š” ํ”„๋กœํ† ์ฝœ์— ์˜์กดํ•˜์—ฌ Mock ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ Test ๊ฐ€๋Šฅํ•œ ์œ„ ๋„คํŠธ์›Œํฌ Layer ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.





๐ŸŒผ Dependency

  1. OAtuh

   ๐Ÿ”˜  FirebaseAuth:  Firebase JWTํ† ํฐ ์ธ์ฆ

   ๐Ÿ”˜  GoogleSignIn:  Google ์†Œ์…œ ๋กœ๊ทธ์ธ

   ๐Ÿ”˜  FacebookLogin:  Facebook ์†Œ์…œ ๋กœ๊ทธ์ธ

   ๐Ÿ”˜  AuthenticationServices:  Apple ์†Œ์…œ ๋กœ๊ทธ์ธ


  2. Push Notification

   ๐Ÿ”˜  FirebaseMessaging:  Firebase Cloud Messaging ์•Œ๋ฆผ


  3. Remote Configuration

   ๐Ÿ”˜  FirebaseRemoteConfig:  Firebase Remote Config, ๊ธด๊ธ‰ ๊ณต์ง€ ํŒ์—…, ์•ฑ ์ตœ์†Œ๋ฒ„์ „ ํ™•์ธ


  4. Log Analysis

   ๐Ÿ”˜  FirebaseAnalytics:  Firebase Analytics, ๋กœ๊ทธ ์ˆ˜์ง‘


  5. Reactive Programming

   ๐Ÿ”˜  RxSwift:  Data Stream์„ ๊ด€์ฐฐํ•˜๋ฉฐ ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ œ๊ณต

   ๐Ÿ”˜  RxDataSources:  Animatable UITableViewCell๊ณผ UICollectionViewCell์˜ Binding

   ๐Ÿ”˜  RxCLLocationManager:  ์œ„์น˜ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” CLLocationManager์˜ Rx Wrapper

   ๐Ÿ”˜  RxKeyboard:  ํ‚ค๋ณด๋“œ ๋†’์ด๋ฅผ Rx์˜ ์ด๋ฒคํŠธ๋กœ ๋ฐฉ์ถœ


  6. AutoLayout

   ๐Ÿ”˜  SnapKit:  ์ฝ”๋“œ ๊ธฐ๋ฐ˜ UI ์„ค๊ณ„


  7. ImageCaching

   ๐Ÿ”˜  Kignfishier:  ๋„คํŠธ์›Œํฌ ๋น„๋™๊ธฐ ์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ์ด๋ฏธ์ง€ ์บ์‹ฑ


  8. Animation

   ๐Ÿ”˜  Lottie:  JSON ์• ๋‹ˆ๋ฉ”์ด์…˜


  9. Progress

   ๐Ÿ”˜  ProgressHUD:  ๋„คํŠธ์›Œํฌ ํ†ต์‹  ์ค‘ ์ธ๋””์ผ€์ดํ„ฐ ํ‘œ์‹œ


  10. PhotoPicker

   ๐Ÿ”˜  YPImagePicker:  ๋ฉ€ํ‹ฐ์ด๋ฏธ์ง€ ๋ฐ Crop ๊ธฐ๋Šฅ ์ง€์›





๐ŸŒผ Notice

ํ•ด๋‹น Commit ์‹œ์ ์—์„œ๋Š” ์„œ๋ฒ„ ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•„ ์™„๋ฃŒ ์‹œ์  ์ด์ „์— ๋™์ž‘ ํ™•์ธ์„ ์›ํ•˜์‹œ๋Š” ๊ฒฝ์šฐ,
"Data - Repository ๊ตฌํ˜„์ฒด ์‹ค์ œ API ๋ชจ๋“œ ์ „ํ™˜" Commit ์ด์ „
Mock Data๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Commit์„ Cloneํ•˜์—ฌ ์‚ฌ์šฉํ•ด์ฃผ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋˜ํ•œ, ๋ฏธ๋ฆฌ ํ˜‘์˜ํ•œ ๋‚ด์šฉ์œผ๋กœ API Endpoint๋ฅผ ์ œ์ž‘ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ ์—ฐ๋™ ํ™•์ธ์ด ํ•„์š”ํ•˜๊ณ ,
ํ•„์š”์‹œ EndPoint ์ˆ˜์ •์ด ํ•„์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ˆ˜์ •์€ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ Bappy - Data - Network์˜ APIEndpoints.swift ๋ฐ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ
DataMapping์˜ ๊ฐ RequestDTO ๋ฐ ResponseDTO๋“ค์˜ ๋‚ด์šฉ ์ผ๋ถ€๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž…, ํ”„๋กœํ•„ ์ˆ˜์ •, ์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ API๋Š” ์„œ๋ฒ„์™€ ์—ฐ๋™์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.