Skip to content

3주차 그룹_피어세션

KYHyeon edited this page Nov 13, 2020 · 2 revisions

WEB

2020.11.13 피어세션

참여 인원
  • 5조

    • 한상욱
    • 강석민
    • 윤현우
  • 9조

    • 박은식
    • 심재익
    • 주재우

피어세션 내용

  1. 자기소개

  2. 각 팀 진행상황 공유

    • 5조

      • backend

        • 기획 단계에서 iOS에서 필요한 API response 내용을 제대로 이야기했어야 했는데, web 위주의 API response를 생각했었다. 그러다 보니 2주차때부터 계속 API 로직이나 response값을 자잘하게 수정하게 됐다.
        • 그 외에도 놓치고 있던 사소한 버그들이 계속 발견되어 발견될 때마다 수정해줬다.
      • frontend

        • 아토믹 디자인 패턴을 처음 사용하였는데 장점으로는 빠른 컴포넌트 생성이였지만 단점으로는 디자인의 자유도가 떨어진다는 것이었다. 또한 리액트를 처음 사용하다 보니 컴포넌트가 불필요하게 랜더링되는 과정이 있었다. 오늘 피어세션때 해결책을 알아서 다행이다. 마지막으로 느낀 것은 불변성을 유지하면서 데이터의 변화를 감지하는 것은 정말 어려운 일이라는 점이고 클라이언트 개발할 때는 사용자의 입장에서 개발해야 된다는 것이다.
    • 9조

      • backend

        • 완성했다고 생각한 backend의 수정은 계속해서 이루어진다!
      • frontend

        • 주요 기능들은 웬만큼 구현을 하였지만 삐걱거리는 부분이 조금씩 남아있었다. 컴포넌트 들을 어떻게 분리하고, 재사용하는 것이 합리적인지는 아직 모르겠다. github Action을 통한 자동배포와 nginx를 통해서 필드한 파일을 올리는 데 성공하였다.
  3. 금주 어려웠던 사항

    • 5조

      • 깃허브 OAuth 를 테스트하기위해서는 프론트와 백엔드 작업이 어느정도 됬어야 했다. 그리고 어떻게 쿠키방식이 아닌 로컬스토리지방식으로 했을까를 고민했는데 간단히 콜백 URL을 따로 만들어 그곳에서 쿠키에 저장된 정보를 스토리지로 옮기고 쿠키를파괴하고 리다이렉트를 사용하는 방식을 생각해냈다.

      • 백엔드 API부분을 미리 다 만들고 프론트 작업을 하는 것이 좋지 않은 선택이라는 것을 뼈저리게 깨달았다. 결국 프론트 작업을 하면서 놓치고 있던 부분들을 확인할 수도 있었고, 눈으로 보여야 실제로 어떤 response가 필요한지 더 쉽게 파악할 수 있었다.

    • 9조

      • 박은식 : 리렌더링이 여러번 되는 문제가 발생하는데 어디서 발생하는지 잡지 못해서 아쉬웠다.
      • 심재익 : 뒤늦게 리액트를 이해한것 같아 모든게 어려웠다.
      • 주재우 : 리엑트의 랜더링 되는 시점에 대해 완벽히 이해하지 못해서 랜더링이 여러번 되는 문제를 해결하지 못해서 아쉬웠다.
  4. 팀 개발을 하며 만족스러웠던 사항

    • 5조

      • 한상욱 : 안 싸우고 빤스런 없이 모두가 완주했다는 것에 박수치고 싶다. 리액트를 처음 했는데 다들 포기하지 않고 컴포넌트 생산에 힘써서 오늘 데모를 할 수 있었다. 또 만나고 싶은 사람들이다. 사람냄새가 나서 좋았던 조이다.
      • 강석민 : 다 같이 리액트가 처음이라 소통이 많은 기간이였다. 짧은기간에 엄청 친해져서 다음 프로젝트도 같이 하길바랬다.
      • 윤현우 : 길고도 짧은 3주가 지나갔다. 개발에 대한 지식이 깊어진 것은 물론이고, 팀 협업에 대한 이해도도 많이 올라갔다. 기획과 팀 협업을 잘 하는 것이 중요하다는 것을 뼈저리게 느낀 3주였다. 우리 팀원분들 모두 정말 감사했고, 앞으로 5주 동안도 체력 잘 관리하면서 원하는 바 모두 이루어넀으면 좋겠다! 그리고 지금처럼 매일 12시까지 하시면 몸이 남아나지 않을 겁니다. 다들 건강 잘 챙기십쇼^_^
    • 9조

      • 박은식 : 복잡한 문제에 대해서 다 같이 고민을 하고 결과를 도출할 수 있어서 좋았다.
      • 심재익 : 정해진 시간마다 모여 자신의 코드에 대해 설명하는 시간이 있어 집중도가 올라갔고, 내 코드에 대해 더 이해하게 되는 계기가 됐다.
      • 주재우 : 문제점에 대해 같이 이야기하면서 해결책을 찾아볼 수 있어서 좋았고, 일정 시간 이후 코드에 대해 설명하는 시간이 있어 내가 구현한 코드 뿐 아니라 팀원의 코드를 잘 이해할 수 있어서 좋았다.
  5. 크롱님의 깜짝 방문! 깜짝(?) 조언 💥

  • '내가 구현한 것들, 다 알고 짰나?' 생각해보자.
  • 데모는 믿지 않는다. 😢 보이는 것들에 치중하지 말자. 😄

[iOS]

피어세션 18 그룹

  • S050 정재명

  • S057 조정래

  • S063 현기엽

  • S010 김승언

우리의 앱

코드 구조

MVVM -> 테스트를 열심히 해보자!

class IssueListViewModel {
    struct Status {
        var issues =  Bindable(IssueListModel.all())
        var searchResultTitleList = Bindable([String]())
        var searchResultList = Bindable(IssueListModel.all())
        var filterResult = Bindable(IssueListModel.all())
    }
    
    struct Action {
        var searchTextChanged: (String) -> Void
        var searchButtonClicked: (String) -> Void
        var searchCancelButtonClicked: () -> Void
        var closeButtonTabbed: (Int) -> Void
        var deleteButtonTabbed: (Int) -> Void
        var refreshData: () -> Void
        var addIssueTabbed: (Int?, String, String) -> Void
        var issueFilter: ([Int]) -> Void
    }
}

    func test_Login_입력아이디가_6자미만이면_유효하지않다() throws {
        
        let id = "12345"
        let viewModel = SignInViewModel()
        
        viewModel.status.buttonEnabled.bind({ idCheck, passwordCheck in
            XCTAssertFalse(idCheck)
        })
        
        viewModel.action.idTextFieldChanged(id)
    }
    

NetworkLayer

func fetchLabels(completion handler: @escaping (Result<Labels, AFError>) -> Void) {
        guard let url = URL(string: baseURL + Endpoint.label.rawValue),
              let token = PersistenceManager.shared.load(forKey: .token) else {
            return
        }
        
        let headers: HTTPHeaders = [.authorization(bearerToken: token)]
        
        AF.request(url,
                   method: .get,
                   headers: headers)
            .validate()
            .responseDecodable(of: Labels.self) { response in
                handler(response.result)
        }
}

DispatchGroup

let dispatchGroup = DispatchGroup()

dispatchGroup.enter() 
function call()

dispatchGroup.leave()

dispatchGroup.notify(queue: DispatchQueue.main) {
    function callback()
}

Coordinator

protocol Coordinator: class {
    var finishDelegate: CoordinatorFinishDelegate? { get set }
    var navigationController: UINavigationController { get set }
    var childCoordinators: [Coordinator] { get set }
    var type: CoordinatorType { get }
    func start()
    func finish()
    
    init(_ navigationController: UINavigationController)
}

extension Coordinator {
    func finish() {
        childCoordinators.removeAll()
        finishDelegate?.coordinatorDidFinish(childCoordinator: self)
    }
}


protocol CoordinatorFinishDelegate: class {
    func coordinatorDidFinish(childCoordinator: Coordinator)
}

enum CoordinatorType {
    case jrm, tab, signIn, signUp, issueList, labelList, milestoneList
}

팀워크

  • 허심탄회하게 Go..! <- 진실게임

디스패치 그룹

reusable cell

  • prepareForUse()
    • 셀을 재사용하기 전에 프로퍼티를 초기화 해주어야 했다....!

URL - 한글

guard let url = (issueAPIURL + "\(oldName)").addingPercentEncoding(
                withAllowedCharacters: .urlQueryAllowed) else { return }
// parameter가 배열일 때, encoder
let encoder = URLEncodedFormParameterEncoder(encoder: URLEncodedFormEncoder(arrayEncoding: .noBrackets))

배열 parameter -> 여기에 대한 키가 이상해짐

  • 웹에서 파싱을 한 번 더 해줘야 또는 인코딩을 해줘야
  • Alamofire 문제

참고 자료