Skip to content

Latest commit

ย 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SeSAC Study

์•ฑ ์†Œ๊ฐœ

  • ๊ฐœ๋ฐœ๊ธฐ๊ฐ„ : 2022.11.07 ~ 2022.12.07(1๊ฐœ์›”)
  • 1์ธ ๊ฐœ๋ฐœ
  • ์œ„์น˜ ๊ธฐ๋ฐ˜ ์Šคํ„ฐ๋”” ๋งค์นญ ์„œ๋น„์Šค
  • Figma, Swagger, Confluence, Notion ์‚ฌ์šฉ

์ฃผ์š” ๊ธฐ๋Šฅ

  • ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ๋กœ ์ธ์ฆ ๋กœ๊ทธ์ธ / ํšŒ์›ํƒˆํ‡ด
  • ์œ„์น˜๊ธฐ๋ฐ˜ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•œ ์ฃผ๋ณ€ ์นœ๊ตฌ ํƒ์ƒ‰
  • ์ฑ„ํŒ… ์š”์ฒญ / ์ˆ˜๋ฝ
  • 1:1 ์ฑ„ํŒ…

๊ธฐ์ˆ  ์Šคํƒ

  • MVVM RxSwift RxDataSource Compositional Layout CodeBaseUI SocketIO RealmSwift Mapkit CoreLocation FirebaseAuth Then Snapkit Alamofire MultiSlider

๊ธฐ์ˆ  ์„ค๋ช…

  • FirebaseAuth๋ฅผ ์ด์šฉํ•˜์—ฌ ํœด๋Œ€ํฐ ์ธ์ฆ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ ๋ฐ ์ •๊ทœ์‹์„ ํ™œ์šฉํ•œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ
  • Compositional Layout๊ณผ RxDataSource๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์—ฐ์Šค๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์ฃผ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋‚˜์€ ๊ฒฝํ—˜์„ ์ œ๊ณต
  • API๊ฐ€ ์ถ”๊ฐ€ ๋ฐ ๋ณ€๊ฒฝ์ด ๋˜๋”๋ผ๋„ ์œ ์ง€๋ณด์ˆ˜์— ํŽธ๋ฆฌํ•˜๋„๋ก Alamofire์™€ URLRequestConvertible์„ ์‚ฌ์šฉํ•˜์—ฌ Router๋ชจ๋“ˆํ™”
  • Firebase Token Manager๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ Token๋งŒ๋ฃŒ์‹œ ๊ฐฑ์‹ ๋˜๋„๋ก ํšจ์œจ์ ์ธ ์„ค๊ณ„
  • Socket IO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ 1:1 ์ฑ„ํŒ… ๊ตฌํ˜„ ๋ฐ Realm์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณผ๋„ํ•œ ์„œ๋ฒ„ ํ˜ธ์ถœ ๋ฐฉ์ง€
  • CoreLocation๊ณผ Mapkit์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ๋ณ€ ์Šคํ„ฐ๋”” ์นœ๊ตฌ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋•Œ Custom Annotation์œผ๋กœ ์ด๋ฏธ์ง€ ํ‘œ์‹œ
  • ํšจ์œจ์ ์ธ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์žฌ์‚ฌ์šฉ ๋ทฐ ์ ๊ทน ํ™œ์šฉ ๋ฐ ๋””์ž์ธ ์‹œ์Šคํ…œ ๋„์ž… Typo System Custom Alert Custom Button๋“ฑ

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

๊ฐœ๋ฐœ์ผ์ง€ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

  • ์Šคํ„ฐ๋”” ๊ฒ€์ƒ‰๋ทฐ ์™ผ์ชฝ ์ •๋ ฌ ๋ ˆ์ด์•„์›ƒ ์ด์Šˆ

    • ๊ธ€์ž์ˆ˜์— ๋”ฐ๋ผ ์…€์˜ ๋„ˆ๋น„๊ฐ€ ์œ ๋™์ ์œผ๋กœ ๋ณ€๋™๋˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์—์„œ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ•˜์˜€๋Š”๋ฐ, ์…€์— ๋ฒ„ํŠผ์„ ๋„ฃ๊ณ  Compositional Layout์„ ์žก์„๋•Œ estimated ์‚ฌ์ด์ฆˆ๋ฅผ ์ฃผ์–ด ํ•ด๊ฒฐ.
      static func fixedSpacedFlowLayout() -> UICollectionViewLayout {
          
          let itemSize = NSCollectionLayoutSize(
              widthDimension: .estimated(100),
              heightDimension: .absolute(32)
          )
          let item = NSCollectionLayoutItem(layoutSize: itemSize)
          
          let groupSize = NSCollectionLayoutSize(
              widthDimension: .fractionalWidth(1.0),
              heightDimension: .estimated(150)
          )
          
          let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
          group.interItemSpacing = NSCollectionLayoutSpacing.fixed(8)
          
          let sectionHeaderPadding: CGFloat = 32
          let section = NSCollectionLayoutSection(group: group)
          section.interGroupSpacing = 8
          section.contentInsets = NSDirectionalEdgeInsets(
              top: 16 + sectionHeaderPadding,
              leading: 16,
              bottom: 8,
              trailing: 16)
          
          let header = NSCollectionLayoutBoundarySupplementaryItem(
              layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(32)),
              elementKind: UICollectionView.elementKindSectionHeader,
              alignment: .topLeading, absoluteOffset: CGPoint(x: 0, y: sectionHeaderPadding))
          
          section.boundarySupplementaryItems = [header]
          
          let layout = UICollectionViewCompositionalLayout(section: section)
          return layout
      }
  • ์Šคํ„ฐ๋”” ๊ฒ€์ƒ‰๋ทฐ ์ค‘๋ณต๊ฐ’ ์ด์Šˆ

    • AnimatedDataSource๋ฅผ ์“ธ๋•Œ Hashableํ•œ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ์„œ ๊ณ„์† ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ. (Diffable๊ณผ ๋™์ผ) RxDataSource ์„น์…˜ ๋ชจ๋ธ์„ ๋งŒ๋“ค๋•Œ IdentifiableType๊ณผ Equatable์„ ์ฑ„ํƒํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฐ์ž์˜ ๊ณ ์œ ์˜ identity๋ฅผ ๊ฐ€์ง€๋„๋ก ํ•˜์—ฌ ๋ฌธ์ œ ํ•ด๊ฒฐ.
    struct StudyList: Hashable {
        let study: String
      
        init(study: String) {
           self.study = study
       }
    }
    
    extension StudyList: IdentifiableType, Equatable {
       var identity: String {
           return UUID().uuidString
       }
    }
  • ์ƒˆ์‹น ์ฐพ๊ธฐ๋ทฐ ์…€ ์žฌ์‚ฌ์šฉ ์ด์Šˆ

    • ๋” ๋ณด๊ธฐ ๋ทฐ๋ฅผ ํŽผ์น ๋•Œ ์…€ ์žฌ์‚ฌ์šฉ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ์„œ ์›ํ•˜๋Š” ์…€์ด ์—ด๋ฆฌ๊ณ  ๋‹ซํžˆ์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ. ์ƒ์„ฑ๋˜๋Š” ์…€ ๊ฐฏ์ˆ˜๋งŒํผ ๋ฐฐ์—ด์— Bool๊ฐ’์„ ๋„ฃ์–ด์„œ ๊ฐ๊ฐ์˜ ์…€์ด true, false ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ ๋ฌธ์ œ ํ•ด๊ฒฐ.
    viewModel.nearSeSAC
        .withUnretained(self)
        .bind { vc, value in
            vc.mainView.setupEmptyStateView(value: value)
            vc.isSelected = Array<Bool>(repeating: false, count: value.count)
        }
        .disposed(by: disposeBag)
    
    viewModel.nearSeSAC
        .asDriver()
        .drive(mainView.tableView.rx.items) { [weak self] (tv, row, item) -> UITableViewCell in
            guard let cell = tv.dequeueReusableCell(withIdentifier: ProfileNickNameTableViewCell.reuseIdentifier, for: IndexPath.init(row: row, section: 0)) as? ProfileNickNameTableViewCell else { return UITableViewCell() }
            cell.firstLineView.moreButton.addTarget(self, action: #selector(self?.moreButtonTapped), for: .touchUpInside)
            cell.firstLineView.moreButton.tag = row
            cell.setupCellData(data: item, buttonType: .request)
            cell.requestButton.rx.tap
                .bind { _ in
                    self?.presentAlert()
                    self?.uid = item.uid
                    print(item.uid)
                }
                .disposed(by: cell.disposeBag)
            if self?.isSelected[row] == true {
                cell.setupExpendedCell(hidden: false, image: Icon.uparrow)
            } else {
                cell.setupExpendedCell(hidden: true, image: Icon.downarrow)
            }
            return cell
        }
        .disposed(by: disposeBag)
  • ์ฑ„ํŒ…UI ์ด์Šˆ

    • ์ฑ„ํŒ… ์ž…๋ ฅ TextView ์„ธ์ค„ ์ œํ•œ์‹œ TextView๊ฐ€ ํ˜„์žฌ ๋ช‡ ์ค„ ์ธ์ง€ ๊ณ„์‚ฐํ•˜์—ฌ ๋†’์ด๋ฅผ ์ œํ•œํ•˜์˜€๋Š”๋ฐ, ๊ธ€์ž๋ฅผ ์ง€์šฐ๋ฉด์„œ TableView์™€์˜ ๋ ˆ์ด์•„์›ƒ์ด ๊นจ์ง€๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒ. lessThan, greaterThan์„ ๋ชจ๋‘ ์„ค์ •ํ•˜์—ฌ ๋ฌธ์ œ ํ•ด๊ฒฐ.
    func setupTextViewDidChange() {
        if textView.numberOfLine() > 3 {
            textView.snp.remakeConstraints { make in
                make.directionalHorizontalEdges.equalToSuperview().inset(16)
                make.bottom.equalTo(self.keyboardLayoutGuide.snp.top).offset(-16)
                make.height.equalTo(90)
            }
            textView.isScrollEnabled = true
        } else {
            textView.snp.remakeConstraints { make in
                make.directionalHorizontalEdges.equalToSuperview().inset(16)
                make.bottom.equalTo(self.keyboardLayoutGuide.snp.top).offset(-16)
                make.height.lessThanOrEqualTo(90)
                make.height.greaterThanOrEqualTo(52)
            }
            textView.isScrollEnabled = false
        }
    }

ํšŒ๊ณ 

  • ์ž˜ํ•œ ์ 

    • Rx์™€ MVVM์ด ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ํฐ ํ”„๋กœ์ ํŠธ์— ์ ์šฉ์‹œํ‚ค๋ฉด์„œ ํ•˜๋А๋ผ ์ฒ˜์Œ์—๋Š” ์กฐ๊ธˆ ๊ณ ์ƒ์„ ๋งŽ์ด ํ–ˆ์ง€๋งŒ, ๋งŽ์€ ์‹œํ–‰์ฐฉ์˜ค ๋์— ๋‚˜๋ฆ„ View์™€ ViewModel์„ ๋ถ„๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
    • ๋ทฐ๋ฅผ ๋งŒ๋“œ๋Š”๊ฒƒ์— ๋Œ€ํ•œ ์ŠคํŠธ๋ ˆ์Šค๊ฐ€ ๊ต‰์žฅํžˆ ์ปธ๋Š”๋ฐ, ์ด๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์–ด๋ ค์›Œ ๋ณด์ด๋Š” ๋ทฐ๋“ค์„ ๋งŒ๋“ค์–ด ๋ณด๋ฉด์„œ ์ด์ œ ๋ทฐ๋ฅผ ๋งŒ๋“œ๋Š”๊ฒƒ์— ๋Œ€ํ•œ ๊ฑฑ์ •๋“ค์ด ๋งŽ์ด ํ•ด์†Œ๋˜์—ˆ๋‹ค.
    • ์—ฌ๋Ÿฌ ์ž‘์€ ์˜ต์…˜์ ์ธ ๊ธฐ๋Šฅ๋“ค์€ ์ œ์™ธํ•˜๊ณ  ํฐ ๊ธฐ๋Šฅ๋“ค์— ์ดˆ์ ์„ ๋‘๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ๋“ค์„ ๋งŽ์ด ์ ์šฉ์‹œ์ผœ ๋ณด๋ ค๊ณ  ํ–ˆ๊ณ , ๊ฒฐ๊ณผ์ ์œผ๋กœ ์˜๋„์— ๋งž๊ฒŒ ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ๋“ค์„ ๋งŽ์ด ๋ฐฐ์šฐ๊ฒŒ ๋˜์—ˆ๋‹ค.
  • ์ž˜๋ชปํ•œ ์ 

    • ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์ดํ•ดํ•˜๋ฉด์„œ ์งœ๋ ค๊ณ  ํ•˜๋Š” ์Šต๊ด€๋•Œ๋ฌธ์— ๋™์ž‘ ๊ตฌ์กฐ๋“ค์„ ์ดํ•ดํ•˜๋Š”๋ฐ์— ์‹œ๊ฐ„์„ ๋„ˆ๋ฌด ๋งŽ์ด ์Ÿ์•˜๊ณ , ๊ฒฐ๊ณผ์ ์œผ๋กœ ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ด์„œ ์ฝ”๋“œ์ ์ธ ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ•ด๋ณด์ง€ ๋ชปํ–ˆ๋‹ค.
    • ์ด๋ฒˆ์— Commit์„ ์Šต๊ด€ํ™” ํ•˜๊ณ , issue๋ฅผ ํ†ตํ•ด Github๋ฅผ ๊ด€๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์‹คํŒจํ–ˆ๋‹ค.
    • ์ฑ„ํŒ… ๊ตฌํ˜„์—์„œ Realm๊ณผ Socket, Server๋“ฑ ๋™์ž‘ ๊ตฌ์กฐ๊ฐ€ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•„์„œ ๋„ˆ๋ฌด ๋งŽ์€ ์‹œ๊ฐ„์„ ๋ฒ„๋ ธ๋‹ค. ๊ทธ๋ƒฅ ํ•ด๋ณด๋ฉด์„œ ๋ชธ์œผ๋กœ ํ„ฐ๋“ํ–ˆ์œผ๋ฉด ํ›จ์”ฌ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์—ˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

About

[๐ŸŒฑ] SeSAC iOS BootCamp Service Level Project

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages