본문 바로가기
모바일앱/iOS

원피스 현상금 랭킹앱 만들기(7) - 코드리뷰

by GeekCode 2021. 11. 10.
반응형

 

이번에 만든 

 

바둑선수는 항상 바둑을 둔 다음 복기를 하는 과정을 갖는다.

회고 : 스스로에 대한 배움을 하는 것이고 그것을 통해 성장하는 것

 

실무에서는 동료들과 코드리뷰라는 과정을 통해 회고를 한다.

왜 이렇게 작성했는지, 이렇게 작성할 경우 실무에서 문제가 생기지는 않을지

지속적으로 코드리뷰를 하다보면 그전에 자가리뷰를 하게 된다.

 

더보기

BountyViewController

//
//  BountyViewController.swift
//  BountyList
//
//  Created by hyeonseok on 2021/10/27.
//

import UIKit

class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
    let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]
    
    //세그웨이를 준비하는 함수 ; UIViewController에 이미 구현되어있는데 상속을 했기때문에 override해야함
    //이때 세그웨이를 사용하면서 필요한 데이터를 알려줘야한다.
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // DetailViewController 에게 데이터를 준다.
        // UITableViewDelegate의 sender로 부터 몇번째 셀인지 받았고 Any?로 받았기 때문에 index를 int로 다운캐스팅
        if segue.identifier == "showDetail"{
            let vc = segue.destination as? DetailViewController
            if let index = sender as? Int {
                vc?.name = nameList[index]
                vc?.bounty = bountyList[index]
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    // UITableViewDataSource
//    //몇개가 필요하니??
//    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//        return 2
//    }
//
//    //어떻게 표현할거니?
//    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
//        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
//        //cell = identifier for -> 셀의 위치
//        return cell
//
//}
//
//    //UITableViewDelegate
//    //어떻게 반응할거야??
//    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//        print("--> \(indexPath.row)")
//    }
    
    
    
    
    
    
    //몇개가 필요하니??
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return bountyList.count
    }

    //어떻게 표현할거니?
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// --> 첫번째 방법
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else {
            return UITableViewCell()
    }
        let img = UIImage(named: "\(nameList[indexPath.row]).jpg")
        cell.imgView.image = img
        cell.nameLabel.text = nameList[indexPath.row]
        cell.bountyLabel.text = "\(bountyList[indexPath.row])"
        return cell
    }
//
//// --> 두번째 방법
//        if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell {
//            let img = UIImage(named: "\(nameList[indexPath.row]).jpg")
//            cell.imgView.image = img
//            cell.nameLabel.text = nameList[indexPath.row]
//            cell.bountyLabel.text = "\(bountyList[indexPath.row])"
//            return cell
//        } else {
//            return UITableViewCell()
//        }
//    }

    // UITableViewDelegate
    // 어떻게 줄거니
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("--> \(indexPath.row)")
        //연결한 segue웨이를 수행하라는 코드 여러개의 세그웨이가 있을수 있어서 구분자 showDetail사용
        //sender가 prepare함수를 사용할 때 몇번째 셀인지 알려주는 역할을 수행
        performSegue(withIdentifier: "showDetail", sender: indexPath.row)
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

class ListCell: UITableViewCell {
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
}

 

 

DetailViewController

//
//  DetailViewController.swift
//  BountyList
//
//  Created by hyeonseok on 2021/10/28.
//

import UIKit

class DetailViewController: UIViewController {
    
    @IBOutlet weak var imgView: UIImageView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var bountyLabel: UILabel!
    
    //BountyView로부터 받아올 변수 지정 (옵셔널)
    var name: String?
    var bounty: Int?
    
    //ViewController가 뜨기 직전, 메모리에 올라왔을 때 ViewDidLoad가 실행된다. 이때 updateUI가 실행됨
    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }
    
    
    //UI컴포넌트들을 업데이트 하는 메서드. 옵셔널바인딩을 사용
    func updateUI() {
        if let name = self.name, let bounty = self.bounty {
            let img = UIImage(named: "\(name).jpg")
            imgView.image = img
            nameLabel.text = name
            bountyLabel.text = "\(bounty)"
        }
    }
    
    @IBAction func close(_ sender: Any) {
        //dismiss 사라지고나서 후에 동작해야할 것들을 적어줌
        dismiss(animated: true, completion: nil)
    }
    
}

 

1. 앱을 보면 현상금이 나와있는데 랭킹앱이긴 하지만 랭킹을 보긴 어렵다. -> 정렬도 되어있지 않다.

 

    let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
    let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]

이름과 순서를 변경하려면 매우 복잡한 과정이 생긴다. 일일히 매칭하는 것을 찾는 것도 굉장히 번거로울 뿐만아니라 

실무로 봤을 때, 에러가 생길 수 있는 것이다.

가장큰 문제는 이름과 현상금이 연결되어있지 않다는 것이다. -> 데이터가 묶여있지않기때문에 각각 접근했다.

 

결과적으로 봤을 때, 코드는 짰지만 고치기가 어렵고 재사용하기 어렵다는 것

기술부채 : 고쳐야 하는데 아직 고치지 못한것 -> 아예 없을 수는 없지만 엔지니어들은 이것을 최소화해야한다.

 

기술부채가 쌓이지 않게 하기위한 개발자들의 전략들이 있다. -> 디자인패턴

다음에 공부할 것은 MVVM패턴이다.

 

 

반응형