ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 'ν˜„μƒκΈˆ λž­ν‚Ή μ•±'을 μ œμž‘ν•˜λ©΄μ„œ 배운 점 회고
    iOS/πŸ€– App 2021. 3. 5. 22:41

    ν˜„μƒκΈˆ λž­ν‚Ή 앱은 3λ‹¨κ³„μ˜ 과정을 κ±°μ³μ„œ μ΅œμ’… 결과물이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

     

    1. MVC νŒ¨ν„΄μ„ 가지고 ν…Œμ΄λΈ” λ·° (UITableView) 와 λ””ν…ŒμΌ λ·° (UIView) 둜 κ΅¬μ„±λœ μ•± μž‘μ„±ν•˜κΈ°

    2. MVC νŒ¨ν„΄μ„ MVVM νŒ¨ν„΄μœΌλ‘œ λ¦¬νŒ©ν„°λ§ν•˜κΈ°

    3. ν…Œμ΄λΈ” λ·°λ₯Ό μ»¬λ ‰μ…˜ 뷰둜 λ³€κ²½ν•˜κ³ , λ””ν…ŒμΌ 뷰에 μ• λ‹ˆλ©”μ΄μ…˜ μΆ”κ°€ν•˜κΈ°

     

    μœ„ λ‹¨κ³„μ˜ μˆœμ„œλŒ€λ‘œ μƒˆλ‘œ λ°°μš°κ±°λ‚˜ λ³΅μŠ΅ν•  점을 κΈ€λ‘œ 남기렀고 ν•©λ‹ˆλ‹€.

     


     

    1단계가 μ™„λ£Œμ‹œμ μ˜ ν˜„μƒκΈˆ λž­ν‚Ή μ•±

     

    1단계: MVC νŒ¨ν„΄μ„ 가지고 ν…Œμ΄λΈ” λ·° 와 λ””ν…ŒμΌ 뷰둜 κ΅¬μ„±λœ μ•± μž‘μ„±ν•˜κΈ°

    a. MVC

    이전 κΈ€μ—μ„œ ν•œ 번 닀룬 λ‚΄μš©μž…λ‹ˆλ‹€.

     

    MVC νŒ¨ν„΄μ˜ νŠΉμ§•μ€ μ•± λ‚΄μ˜ 였브젝트λ₯Ό 3개의 큰 μ—­ν•  (λ ˆμ΄μ–΄) 둜 λ‚˜λˆ„κ³ , μ—­ν•  κ°„ μ΄μƒμ μœΌλ‘œ μ†Œν†΅ν•˜λŠ” 방식이 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

    Model, View, Contoller : View 와 Model μ—λŠ” 직접적인 연결성이 μ—†λ‹€. Controller κ°€ 두 λ ˆμ΄μ–΄μ˜ μ€‘μž¬μžμ΄λ‹€.

     

    그리고 Controller λ ˆμ΄μ–΄μ— μ†ν•˜λŠ” UIViewController 의 역할이 λ„ˆλ¬΄ λΉ„λŒ€ν•΄μ Έ 'Massive View Controller' κ°€ λœλ‹€λŠ” 단점이 μžˆμŠ΅λ‹ˆλ‹€.

    μ΄λ ‡κ²Œ 되면 SOLID 쀑 ν•˜λ‚˜μΈ 단일 μ±…μž„μ˜ 원칙에 μ–΄κΈ‹λ‚˜κΈ° λ•Œλ¬Έμ— μœ μ§€λ³΄μˆ˜μ™€ μ½”λ“œμ˜ μž¬μ‚¬μš©, ν…ŒμŠ€νŠΈκ°€ μ–΄λ €μ›Œμ§‘λ‹ˆλ‹€.


     

    b.  ν…Œμ΄λΈ” λ·°

    ν…Œμ΄λΈ” λ·°λŠ” 리슀트 자료ꡬ쑰λ₯Ό 화면에 ν‘œν˜„ν• λ•Œ μ ν•©ν•œ View μž…λ‹ˆλ‹€.

     

    ν…Œμ΄λΈ” 뷰의 ν˜•νƒœμ  νŠΉμ§•μ€ λ°˜λ“œμ‹œ ν•˜λ‚˜μ˜ 행에 ν•˜λ‚˜μ˜ cell λ§Œμ„ ν‘œμ‹œν•  수 μžˆλ‹€λŠ” 것 μž…λ‹ˆλ‹€.

     

    λ˜ν•œ Delegation 을 톡해

    1. ν…Œμ΄λΈ” 뷰에 ν‘œμ‹œν•  데이터와 - UITableViewDataSource

     

    2. ν…Œμ΄λΈ” λ·°μ—μ„œ μ΄λ²€νŠΈκ°€ λ°œμƒν–ˆμ„ λ•Œ μ²˜λ¦¬ν•  λ©”μ†Œλ“œλ₯Ό μš”κ΅¬ν•©λ‹ˆλ‹€. - UITableViewDelegate

     

    Delegation 은 객체가 μ†Œν†΅ν•˜λŠ” 방식 쀑 ν•˜λ‚˜ μž…λ‹ˆλ‹€.

     

    객체가 μ†Œν†΅ν•˜λŠ” 방식은 크게 3가지가 있으며, Delegation, Notification, KVO 방식이 μžˆμŠ΅λ‹ˆλ‹€.

    Notification, KVO 방식은 μΆ”ν›„ 글을 톡해 λ‹€λ£° μƒκ°μž…λ‹ˆλ‹€.

     

    또 λ‹€λ₯Έ νŠΉμ§•μœΌλ‘œλŠ” cell 을 μž¬ν™œμš© ν•œλ‹€λŠ” 점이 μžˆμŠ΅λ‹ˆλ‹€.

     

    즉 화면에 cell 을 ν‘œμ‹œν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” 것이 μ•„λ‹ˆλΌ, ν•œ 번 μ‚¬μš©ν•œ cell 을 버퍼에 λ”°λ‘œ μ €μž₯해놓고 μž¬ν™œμš©ν•  cell 이 있으면 μž¬ν™œμš©ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.

     

    μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œμΈ dequeReusableCell(withIdentifier:for:) λ“±μ˜ λ©”μ†Œλ“œλ‘œ cell을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

    μž¬ν™œμš©ν•  cell 이 없을 κ²½μš°μ—λŠ” μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄μ„œ λ°˜ν™˜ν•©λ‹ˆλ‹€.

     

    이 ν”„λ‘œμ νŠΈμ—μ„œλŠ” μ»€μŠ€ν…€ 셀을 μ‚¬μš©ν•˜μ˜€κΈ° λ•Œλ¬Έμ— μ•„λž˜ μ½”λ“œμ™€ 같은 λ°©μ‹μœΌλ‘œ νƒ€μž… μΊμŠ€νŒ… (as?) ν•˜μ—¬ μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

    μ™œ νƒ€μž… μΊμŠ€νŒ…? 이 λ©”μ„œλ“œκ°€ λ°˜ν™˜ν•˜λŠ” νƒ€μž…μ€ UITableViewCell 이기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

    guard let cell = tableView.dequeueReusableCell(withReuseIdentifier: "ListCell", for: indexPath) as? ListCell else { return UITableViewCell() }

     

    c. λ””ν…ŒμΌ λ·°

     

     

    이 μ•±μ—μ„œλŠ” Bounty List View Controller 와 Detail View Controllerκ°€ Segue (세그웨이) 둜 μ—°κ²°λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

    Presentation 방식은 'Present Modally' μž…λ‹ˆλ‹€.

     

    보톡 컨트둀과 View Controller λ₯Ό μ„Έκ·Έμ›¨μ΄λ‘œ μ—°κ²°ν•˜λ©΄

    μ»¨νŠΈλ‘€μ—μ„œ μ§€μ •ν•œ μœ μ € 인풋이 λ°œμƒν•˜λ©΄ μžλ™μœΌλ‘œ 세그웨이가 μ‹€ν–‰ λ©λ‹ˆλ‹€.

    μ»¨νŠΈλ‘€μ€ User Interaction 을 Default 둜 λ°›λŠ” UIVIew 듀을 λ§ν•©λ‹ˆλ‹€.

     

    ν•˜μ§€λ§Œ VC와 VC κ°„μ˜ 세그웨이 연결은 말 κ·ΈλŒ€λ‘œ VC κ°„μ˜ μ—°κ²°μ„±λ§Œ λ‚˜νƒ€λ‚Ό 뿐, SegueλŠ” μžλ™μœΌλ‘œ μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

     

    λ”°λΌμ„œ μ›ν•˜λŠ” μ‹œμ μ— performSegue(withIdentifier:sender:) 와 같은 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ 세그웨이λ₯Ό μˆ˜λ™μœΌλ‘œ μ‹€ν–‰μ‹œμΌœμ•Ό ν•©λ‹ˆλ‹€.

     

    μ„Έκ·Έμ›¨μ΄μ˜ Attribute Inspector

     

    그리고 VC와 VC κ°„μ—λŠ” μ—¬λŸ¬ 세그웨이가 μ‘΄μž¬ν•  수 있기 λ•Œλ¬Έμ—, μ„Έκ·Έμ›¨μ΄λ§ˆλ‹€ identifier λ₯Ό 지정해 μ€λ‹ˆλ‹€.

     

    예λ₯Ό λ“€μ–΄ performSegue(withIdentifier:sender:) λ©”μ„œλ“œλŠ” 첫번째 νŒŒλΌλ―Έν„°λ‘œ 이 identifier λ₯Ό μš”κ΅¬ν•©λ‹ˆλ‹€.

     

    perfromSegue(withIdentifier:sender) λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λ©΄ μ—°κ²°λ˜μ–΄μžˆλŠ” λ‹€μŒ VC κ°€ 화면에 λ‚˜νƒ€λ‚˜κΈ° 직전에

     

    prepare(for:sender:) λ©”μ„œλ“œκ°€ 호좜 λ©λ‹ˆλ‹€.

     

    prepare(for:sender:) λ©”μ„œλ“œμ˜ μ›ν˜•μ—λŠ” μ•„λ¬΄λŸ° μ½”λ“œκ°€ λ“€μ–΄μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

     

    λ”°λΌμ„œ μ˜€λ²„λΌμ΄λ“œ ν•΄μ„œ μ›ν•˜λŠ” λŒ€λ‘œ κ΅¬ν˜„ ν•©λ‹ˆλ‹€.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      guard segue.identifier == "detailView", let sender = sender as? Int else {
        return
      }
    
      guard let vc = segue.destination as? DetailViewController else {
        return
      }
    
      vc.name = nameList[sender]
      vc.bounty = bountyList[sender]
    
    }

     

    첫번째 νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬λœ segue λŠ” μ‹€ν–‰λœ μ„Έκ·Έμ›¨μ΄μ˜ μ°Έμ‘°λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€.

     

    identifier, source, destination 속성을 μ μ ˆν•˜κ²Œ μ‚¬μš©ν•˜μ—¬ 두 객체 (VC) κ°„μ˜ 데이터 전달을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    μ—¬κΈ°μ„œ source 와 destination 은 UIViewController νƒ€μž…μ΄λ―€λ‘œ λ§žλŠ” 클래슀둜 νƒ€μž… μΊμŠ€νŒ…ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

     

    λ‘λ²ˆμ§Έ νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬λœ sender λŠ” perfromSegue(withIdentifier:sender) μ„ ν˜ΈμΆœν• λ•Œ μ „λ‹¬ν•œ sender 와 같은 데이터 μž…λ‹ˆλ‹€.

     

    μœ„ μ½”λ“œμ—μ„œλŠ” indexPath.row λ₯Ό μ „λ‹¬ν•˜μ˜€κ³ , Any? νƒ€μž…μœΌλ‘œ λ°›μ•˜κΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•˜κΈ° μœ„ν•΄ Int 둜 νƒ€μž…μΊμŠ€νŒ…ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

     

     

     

    끝!


    λ‹€μŒ κΈ€:

     

     

    λŒ“κΈ€

μ–΄μ œλ³΄λ‹€ λ°œμ „ν•œ λ‚˜