Skip to content

๐Ÿงก ใ…ค๋ธ๋ฆฌ๋ง๋ฆฌ ํฌ๋ชจ์ŠคํŠธ ์•„์š”ใ…ค๐Ÿงก

Notifications You must be signed in to change notification settings

TeamMyDaily/4most-iOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Jan 17, 2021
f2130b6 ยท Jan 17, 2021
Jan 17, 2021
Dec 29, 2020
Jan 15, 2021

Repository files navigation


๐Ÿงญ 4Most

์ด์ƒ์ด ์ผ์ƒ์ด ๋˜๋Š” ํšŒ๊ณ , 4most

๊ฐœ๋ฐœ๊ธฐ๊ฐ„: 2020.12.27 ~ 2021.01.16


๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป Team4Most - iOS Developer

์ด์œ ์ง„ ์‹ ์œค์•„ ์žฅํ˜œ๋ น
lee-yujinn YoonAh-dev hryeong66
๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž…
๊ธฐ๋ก
๋ชฉํ‘œ
ํšŒ๊ณ 
๋งˆ์ดํŽ˜์ด์ง€ ์„ค์ •
ํ‚ค์›Œ๋“œ ์„ค์ •
๋งˆ์ดํŽ˜์ด์ง€ ํ‚ค์›Œ๋“œ


โš™๏ธ ๊ฐœ๋ฐœํ™˜๊ฒฝ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

swift xcode iOS Moya Alamofire lottie-ios


๐Ÿ–ผ ์„œ๋น„์Šค Workflow

flow

๐Ÿ“ฑ ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ

์ฃผ์š”๊ธฐ๋Šฅ ์ƒ์„ธ๊ธฐ๋Šฅ ์šฐ์„ ์ˆœ์œ„ ๋‹ด๋‹น์ž ๊ตฌํ˜„
๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ P1 ์ด์œ ์ง„ โญ•๏ธ
์ž๋™๋กœ๊ทธ์ธ P2 ์ด์œ ์ง„ โญ•๏ธ
ํ‚ค์›Œ๋“œ ์„ค์ • ํ‚ค์›Œ๋“œ ์„ ํƒ P1 ์žฅํ˜œ๋ น โญ•๏ธ
ํ‚ค์›Œ๋“œ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ P1 ์žฅํ˜œ๋ น โญ•๏ธ
ํ‚ค์›Œ๋“œ ์šฐ์„ ์ˆœ์œ„ ์ง€์ • P1 ์žฅํ˜œ๋ น โญ•๏ธ
ํ‚ค์›Œ๋“œ ์ •์˜ ์ž‘์„ฑ P1 ์žฅํ˜œ๋ น โญ•๏ธ
๊ธฐ๋ก ๊ธฐ๋ก ๋‚ ์งœ๋ณ„ ์กฐํšŒ P1 ์ด์œ ์ง„ โญ•๏ธ
ํ‚ค์›Œ๋“œ ๋ณ„ ๊ธฐ๋ก ์ถ”๊ฐ€ P1 ์ด์œ ์ง„ โญ•๏ธ
๊ธฐ๋ก ์ƒ์„ธ ํŽ˜์ด์ง€ P1 ์ด์œ ์ง„ โญ•๏ธ
๊ธฐ๋ก ์ˆ˜์ • ๋ฐ ์‚ญ์ œ P1 ์ด์œ ์ง„ โญ•๏ธ
๊ธฐ๋ก ๋‚ ์งœ ๋ณ€๊ฒฝ P1 ์ด์œ ์ง„ โญ•๏ธ
๋ชฉํ‘œ ๋ชฉํ‘œ ์ฃผ์ฐจ๋ณ„ ์กฐํšŒ P2 ์ด์œ ์ง„ โญ•๏ธ
๋ชฉํ‘œ ์ƒ์„ธ ํŽ˜์ด์ง€ P2 ์ด์œ ์ง„ โญ•๏ธ
ํ‚ค์›Œ๋“œ ๋ณ„ ๋ชฉํ‘œ ์ถ”๊ฐ€ P2 ์ด์œ ์ง„ โญ•๏ธ
๋ชฉํ‘œ ์ˆ˜์ • ๋ฐ ์‚ญ์ œ P2 ์ด์œ ์ง„ โญ•๏ธ
๋ชฉํ‘œ ๋‹ฌ์„ฑ์—ฌ๋ถ€ ์ฒดํฌ P2 ์ด์œ ์ง„ โญ•๏ธ
๋ชฉํ‘œ ์ฃผ์ฐจ ๋ณ€๊ฒฝ P2 ์ด์œ ์ง„ โญ•๏ธ
ํšŒ๊ณ  ๋ฆฌํฌํŠธ ์กฐํšŒ P1 ์‹ ์œค์•„ โญ•๏ธ
ํ‚ค์›Œ๋“œ ๋ณ„ ๋ฆฌํฌํŠธ ์กฐํšŒ P1 ์‹ ์œค์•„ โญ•๏ธ
ํšŒ๊ณ  ์กฐํšŒ P1 ์‹ ์œค์•„ โญ•๏ธ
ํšŒ๊ณ  ์ž‘์„ฑ P1 ์‹ ์œค์•„ โญ•๏ธ
ํšŒ๊ณ  ์ฃผ์ฐจ ๋ณ€๊ฒฝ P1 ์‹ ์œค์•„ โญ•๏ธ
๋งˆ์ดํŽ˜์ด์ง€ ํ‚ค์›Œ๋“œ ์šฐ์„ ์ˆœ์œ„ ๋ณ€๊ฒฝ P2 ์žฅํ˜œ๋ น โญ•๏ธ
ํ‚ค์›Œ๋“œ ์ •์˜ ์กฐํšŒ P2 ์žฅํ˜œ๋ น โญ•๏ธ
ํ‚ค์›Œ๋“œ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ P2 ์žฅํ˜œ๋ น โญ•๏ธ
๊ธฐ๋ก ํ‚ค์›Œ๋“œ ๋“ฑ๋ก ๋ฐ ํ•ด์ œ P2 ์žฅํ˜œ๋ น โญ•๏ธ
์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒ P3 ์‹ ์œค์•„ โญ•๏ธ
๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ P3 ์‹ ์œค์•„ โญ•๏ธ
ํšŒ์›ํƒˆํ‡ด P3 ์‹ ์œค์•„ โญ•๏ธ

โœ… ๊ฐœ๋ฐœ ์„ค๋ช…

  1. ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    • ํ‚ค์›Œ๋“œ ์„ค์ •

       //KeywordSettingTVC - tableviewcell ์•ˆ์— ๋ฒ„ํŠผ ํด๋ฆญ delegate
           protocol SelectKeywordDelegate {
             func addSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) -> Bool
      
             func cancelSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String)
           }
      
           }
      
       ///KeywordSettingVC
           extension KeywordSettingVC: SelectKeywordDelegate{
             func addSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) -> Bool{
                 if selectedKeywordCount >= 8{
                     alertKeyword()
                     return false
                 }else{
                     if attitudeOfWork.contains(selectedText){
                         selectedKeywordList[1].append(selectedText)
                     }else{
                         selectedKeywordList[0].append(selectedText)
                     }
                     selectedKeywordCount += 1
                     setButtonActive()
                     return true
                 }
             }
      
             func cancelSelectedKeyword(_ cell: KeywordSettingTVC, selectedText: String) {
                 var keywordIndex = -1
      
                 for i in 0...2{
                     keywordIndex = selectedKeywordList[i].firstIndex(of: selectedText) ?? -1
                     if keywordIndex != -1{
                         selectedKeywordList[i].remove(at: keywordIndex)
                         selectedKeywordCount -= 1
                         setButtonActive()
                     }
                 }
             }
         }

      tableview cell ์•ˆ์— ํ‚ค์›Œ๋“œ ๋ฒ„ํŠผ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ, ๊ทธ ๋ˆŒ๋ฆฌ ๋ฒ„ํŠผ์˜ ์ด๋ฆ„์ด ๋ฌด์—‡์ด์—ˆ๋Š”์ง€, ํ˜„์žฌ ๋ˆŒ๋ฆฐ ๋ฒ„ํŠผ์€ ๋ช‡๊ฐœ์ธ์ง€๋ฅผ ์•Œ์•„์•ผํ–ˆ๋‹ค. ๋‹ค๋ฅธ ๊ณ„์ธต์˜ ๋ทฐ ์‚ฌ์ด์˜ ์ •๋ณด๋ฅผ ์ฒ˜์Œ์—๋Š” ์–ด๋–ป๊ฒŒ ์ฃผ๊ณ  ๋ฐ›์„์ง€ ๋ชฐ๋ผ static ๋ณ€์ˆ˜๋กœ ๋ˆŒ๋ฆฐ ๊ฐฏ์ˆ˜๋ฅผ +,- ํ–ˆ๋‹ค. ๊ทธ static ๋ณ€์ˆ˜๊ฐ€ 8๊ฐœ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ delegate๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•˜์˜€๋‹ค. ํ•˜์œ„ ๋ทฐ์— cell์— delegate ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ทธ ํ•จ์ˆ˜๋ฅผ ์ƒ์œ„์ธ VC์—์„œ ๊ตฌํ˜„ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์•˜๋‹ค.

    • ๊ธฐ๋ก

      @IBAction func btnMoreTapped(_ sender: Any) {
              if sender is UIButton {
                  isExpanded = !isExpanded
                  
                  sizingLabel.numberOfLines = isExpanded ? 0 : 1
                  labelBody.textColor = isExpanded ? UIColor.mainLightGray3 : UIColor.white
                  labelBody.font = .myRegularSystemFont(ofSize: 15)
                  sizingLabel.font = .myRegularSystemFont(ofSize: 15)
                  buttonMore.setImage(isExpanded ? UIImage(named: "btn_chevron_down"): UIImage(named: "btn_chevron_up"), for: .normal)
                  
                  delegate?.moreTapped(cell: self)
              }
          }
      
       func moreTapped(cell: DetailTVC) {
              tableView.beginUpdates()
              tableView.endUpdates()
          }

      ๊ธฐ๋ก์˜ ๊ฐœ์ˆ˜์— ๋งž๊ฒŒ ๋“œ๋กญ๋‹ค์šด์ด ๋˜๋ฉฐ ์ •๋ณด๊ฐ€ ๋ณด์—ฌ์ ธ์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ํ…Œ์ด๋ธ”๋ทฐ์˜ ๊ธธ์ด๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ–ˆ์–ด์•ผ ํ–ˆ๋‹ค. ํƒญ์ด ๋ˆŒ๋ฆฌ๋ฉด tableview๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ์žก์„ ์ˆ˜ ์žˆ๊ฒŒ ๋™์ ์ธ ๊ธธ์ด๋ฅผ ๊ฐฑ์‹ ๋˜์–ด์•ผ ํ•ด์„œ ํ…Œ์ด๋ธ”๋ทฐ์˜ ๊ธธ์ด๋Š” estimatedRowHeight๋กœ ์ดˆ๊ธฐ์— ์žก๊ณ  automaticDimension์„ ์ ์šฉ์‹œ์ผœ์ฃผ์–ด ๊ตฌํ˜„ํ–ˆ๋‹ค.

    • ํšŒ๊ณ 

      func collectionView(_ collectionView: UICollectionView, heightForLabelAtIndexPath indexPath: IndexPath) -> CGFloat {
              let width = (collectionView.bounds.size.width - (collectionView.contentInset.left + collectionView.contentInset.right + 16 + 16 + 30)) / 2 - 30
              let label: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
              label.text = taskTitle[indexPath.item]
              label.preferredMaxLayoutWidth = width
              label.numberOfLines = 0
              label.lineBreakMode = NSLineBreakMode.byWordWrapping
              label.contentMode = .scaleToFill
              label.font = .myBoldSystemFont(ofSize: 16)
              label.sizeToFit()
              
              let calculateHeight = label.intrinsicContentSize.height + 120
              return calculateHeight
          }

      ํšŒ๊ณ ๋ทฐ์—์„œ ํ‚ค์›Œ๋“œ๋ณ„ ๋ฆฌํฌํŠธ ์ƒ์„ธ ๊ธฐ๋ก์„ ์กฐํšŒํ•  ์‹œ ํ•ด๋‹น ํ–‰๋™ ๊ธฐ๋ก text๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Label ํฌ๊ธฐ์— ๋”ฐ๋ผ ์…€์˜ height ํฌ๊ธฐ๊ฐ€ ๊ฐ๊ฐ ๋‹ค๋ฅธ UICollectionView๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ UICollectionViewLayout ํŒŒ์ผ์„ ๋”ฐ๋กœ ์ƒ์„ฑํ•ด collectionView์˜ ๋†’์ด๋ฅผ ์ƒ์„ฑํ•˜๋Š” collectionView ํ•จ์ˆ˜๋ฅผ overrideํ•˜์—ฌ Label์— ๋”ฐ๋ผ์„œ ์…€ ํฌ๊ธฐ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜ collectionView๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ•จ์ˆ˜์—์„œ๋Š” ๋“ค์–ด๊ฐ€๋Š” Label์˜ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•ด๋‚ด์–ด ๊ฐ ์…€๋งˆ๋‹ค ๋‹ค๋ฅธ ๋†’์ด๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

  2. Extension์„ ํ†ตํ•ด ์ž‘์„ฑํ•œ ๋ฉ”์†Œ๋“œ ์„ค๋ช…

    • Extension+Date

      extension Date {
          var startOfWeek: Date? {
              var gregorian = Calendar(identifier: .gregorian)
              gregorian.timeZone = TimeZone(secondsFromGMT: 0)!
              guard let monday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
              if Calendar.current.component(.weekday, from: monday) == 1{ //์ผ์š”์ผ์ผ๋•Œ
                  return gregorian.date(byAdding: .day, value: 1, to: monday)
              }else{
                  return gregorian.date(byAdding: .day, value: 2, to: monday)
              }
          }
          
          var endOfWeek: Date? {
              var gregorian = Calendar(identifier: .gregorian)
              gregorian.timeZone = TimeZone(secondsFromGMT: 0)!
              guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
              if Calendar.current.component(.weekday, from: self) == 1{ //์ผ์š”์ผ์ผ๋•Œ
                  return gregorian.date(byAdding: .day, value: 2, to: sunday)
              }else{
                  return gregorian.date(byAdding: .day, value: 7, to: sunday)
              }
          }
      }

      ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์—์„œ ํ˜„์žฌ ์‹œ์  ์ฃผ์ฐจ์˜ ์‹œ์ž‘๋‚ ์งœ์™€ ๋งˆ์ง€๋ง‰๋‚ ์งœ๋ฅผ ์œ ๋‹‰์Šคํƒ€์ž„์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

      iOS์—์„œ ์ œ๊ณต๋˜๋Š” Calendar๋Š” ๋งค์ฃผ ์ผ์š”์ผ์„ ์ฃผ์˜ ์‹œ์ž‘์œผ๋กœ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›”์š”์ผ๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•˜๋Š” ํฌ๋ชจ์ŠคํŠธ์—๋Š” ๋งž์ง€ ์•Š์•„ ์ผ์š”์ผ์ธ ๊ฒฝ์šฐ๋ฅผ ์˜ˆ์™ธ์ ์œผ๋กœ ๊ณ„์‚ฐํ•ด์„œ ํ˜„์žฌ ์‹œ์ ์˜ ์‹œ์ž‘๊ณผ ๋ ๋‚ ์งœ๋ฅผ ๋ฆฌํ„ด!


๐Ÿค 4Mosts Code Convention Rule

๋„ค์ด๋ฐ

  • ํ•จ์ˆ˜

      func set4Most() {
      } 
      lowerCamelCase ์‚ฌ์šฉํ•˜๊ณ  ๋™์‚ฌ๋กœ ์‹œ์ž‘
  • ๋ณ€์ˆ˜

      var fourMostMembers = 13
      lowerCamelCase ์‚ฌ์šฉ
  • ์ƒ์ˆ˜

      let fourMostiOSDevelopers: [String] = ["์œ ์ง„", "์œค์•„", "ํ˜œ๋ น"]
      lowerCamelCase ์‚ฌ์šฉ
  • ํด๋ž˜์Šค

      class fourMost{
      }
      UpperCamelCase ์‚ฌ์šฉ
  • ํŒŒ์ผ๋ช…

    ์•ฝ์–ด
    ViewController VC
    TableViewCell TVC
    CollectionViewCell CVC
  • ๋ฉ”์„œ๋“œ

    • ์„ค์ • ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋Š” set์œผ๋กœ ์‹œ์ž‘
        func setNavigationBar() {
        }

๊ธฐํƒ€๊ทœ์น™

  • self๋Š” ์ตœ๋Œ€ํ•œ ์‚ฌ์šฉ์„ ์ง€์–‘

  • viewDidLoad()์—์„œ๋Š” ํ•จ์ˆ˜ํ˜ธ์ถœ๋งŒ

    • delegate ์ง€์ •, UI๊ด€๋ จ ์„ค์ • ๋“ฑ๋“ฑ ๋ชจ๋‘ ํ•จ์ˆ˜๋กœ
  • ํ•จ์ˆ˜๋Š” extension์— ์ •์˜ํ•˜๊ณ  ์ •๋ฆฌ

    • extension์€ ๋ชฉ์ ์— ๋”ฐ๋ผ ๋ถ„๋ฅ˜

๐ŸŽ 4Mosts Team Rule

git

๐Ÿ”€ git branch

  • master : ์ œํ’ˆ์œผ๋กœ ์ถœ์‹œ๋  ์ˆ˜ ์žˆ๋Š” ๋ธŒ๋žœ์น˜
  • develop : ๋‹ค์Œ ์ถœ์‹œ ๋ฒ„์ „์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋ธŒ๋žœ์น˜
  • feature : ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋ธŒ๋žœ์น˜
  • release : ์ด๋ฒˆ ์ถœ์‹œ ๋ฒ„์ „์„ ์ค€๋น„ํ•˜๋Š” ๋ธŒ๋žœ์น˜

โœŒ๏ธ git commit message

  • [Feat] : ๊ธฐ๋Šฅ์ถ”๊ฐ€
  • [Fix] : ๋ฒ„๊ทธ์ˆ˜์ •
  • [Chore] : ๊ฐ„๋‹จํ•œ ์ˆ˜์ •
  • [Docs] : ๋ฌธ์„œ ๋ฐ ๋ฆฌ๋“œ๋ฏธ ์ž‘์„ฑ
  • [Merge] : ๋จธ์ง€

project foldering

  • Resourse : asset, info.plist, AppDelegate ๊ด€๋ฆฌ

  • Source : Scene(flow ๋ณ„๋กœ ํด๋”๋ง) -> Storyboard, VC, Network(API), Model ๋“ฑ ๊ด€๋ฆฌ

    4Most_iOS
      |โ”€โ”€ Source
      โ”‚   โ””โ”€โ”€ Scene
      โ”‚         โ”œโ”€โ”€ MyDaily.storyboard
      โ”‚         โ”œโ”€โ”€ View
      โ”‚         โ”‚     โ”‚โ”€โ”€ Cell
      โ”‚         โ”‚     โ””โ”€โ”€ VC
      โ”‚         โ””โ”€โ”€ Network
      โ”‚               โ””โ”€โ”€ Service
      โ”‚               โ””โ”€โ”€ Response
      โ”‚               โ””โ”€โ”€ Resquest
      โ””โ”€โ”€ Resource 
         |โ”€โ”€ Assets.xcassets
         |โ”€โ”€ LaunchScreen.storyboard
         |โ”€โ”€ AppDelegate.swift
         |โ”€โ”€ SceneDelegate.swift
         โ””โ”€โ”€ Info.plist
    
    

About

๐Ÿงก ใ…ค๋ธ๋ฆฌ๋ง๋ฆฌ ํฌ๋ชจ์ŠคํŠธ ์•„์š”ใ…ค๐Ÿงก

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published