let:us Go! 2018 여름

첫 번째: Xcode에서 디버깅 시작하기

재성 님

(늦게 가서 조금 밖에 못 들었다… 나중에 자료가 나오면 정리해야겠다.)

View hierarchy

뷰 계층 구도를 볼 수 있음. 각 뷰 간의 거리를 벌리거나 isHidden 값을 조정하는 버튼, constaints를 보는 버튼 등이 있음.

DEBUG

#if DEBUGendif 문구를 사용해 개발 시에만 로그를 찍을 때 유용하게 사용할 수 있음.

두 번째: 코드 응집도 높이기

곰튀김 님

  • 응집도
    SOLID에서 나오는 이론적인 이야기지만 오늘은 단순하게! 코드의 응집도를 높이자!

장점

다음과 같은 것들이 쉬워진다.

  • Read
  • Follow
  • Maintenance

이것을 하기 위해서 관련 있는 것들끼리 묶어 놓자.

응집도를 높이는 방법

  1. Data, Logic, UI끼리 묶기
  2. Data Setter
    DidSet을 set하는 부분을 묶자.
  3. Overrides
    상위 View Controller를 두고 그것을 다시 상속해 클로저로 할 일을 전달.
  4. Selector
    Wrapper 클래스를 만들어서 그 안에서 Selector를 처리하게 하고 실제에서는 클로저만 전달.
  5. Delegate
    마찬가지로 Wrapper 클래스를 만들어서 클로저로 전달.

Elegant way

  1. Data, Login, UI끼리 묶기: 따로 파일을 만들어서 응집시키기
  2. Data Setter: Rx를 사용해서 모으기
  3. Overrides: RxViewController를 사용해서 기본 제공되는 메서드에 클로저를 전달.
  4. Selector
    기본 알림 메서드를 사용해 클로저를 전달.
  5. Delegate
    Reactive에 대한 extension를 만들어서 Proxy를 사용해 .rx를 통해 응집도를 높일 수 있다.

결국 이렇게 되면 Context의 역할이 ViewModel과 같아지고 MVVM 패턴과 같아진다. 여기서 중요한 것은 ViewModel이 ViewController를 보지 말아야 한다는 것. 단방향으로 쭉 이어지게끔 한다.

세 번째: Observable Operator 적재적소 사용하기

엉덩숭아 님

FlatMap

문제점: 버튼 이벤트를 1초 간격으로 3번 일어나게 한다고 했을 때 빠르게 버튼을 탭할 경우 이벤트들이 엮일 수 있다.

  • FlatMapFirst: 먼저 생성된 옵저버블이 끝나기 전까지 들어오는 이벤트를 무시한다.
    사용 예: 서버 요청을 한 번 한 후에는 그 다음 요청을 안 하게 할 수 있음.
  • FlatMapLatest: 이벤트가 들어오면 앞에 생성된 옵저버블을 무시한다.
    사용 예: 응답이 중요하지 않고 단지 API 요청을 보내는 것이 중요할 때.

Side Effect

외부에 영향을 주거나 받는 경우. 한 예로 self로 클로저 외부의 값에 직접 접근해 가져오는 경우에 발생한다.

사이드 이펙트가 있으면 안되는

  • map
  • flatMap

사이드 이펙트가 있어도 괜찮은

  • do
  • subscribe

이것을 해결하기 위해서 withLatestFrom 메서드를 사용한다. 이 메서드는 어떤 Observable의 가장 마지막 이벤트를 받아오겠다는 뜻. 외부의 값을 인자로 넣어 그것을 매개변수로 받아온다.

Window

이벤트들을 인자로 전달한 갯수만큼 모아서 작은 오퍼레이터로 다시 만들어 준다. 이것을 subscribe해서 적절한 처리를 할 수 있다.

Scan

Observable이 배출한 항목에 연속적으로 함수를 적용하고 실행한 후 성공적으로 실행된 함수의 리턴 값을 발행한다.

Switch

Observable들을 배출하는 Observable을 싱글 Observable로 변환한다. 변환된 싱글 Observable은 변환 전 소스 Observable들이 배출한 항목들을 배출한다. -> 내부의 옵저버블을 새 옵저버블로 갈아치운다.

네 번째: iOS TDD 실무에 적용하기

AnyObject 님

TDD를 하려면?

  1. 팀 동료 설득하기: “안 해본 것”에 대한 두려움 -> “지식”을 전달하자!
  • 동료를 설득하기 전에 ‘내가 그것을 실현할만한 충분한 개발적 역량을 가지고 있는지?’, ‘그 역량으로 신뢰받고 있는지’를 되돌아봐야 함.
  • 가르쳐 주는 것이 아니라 같이 찾아보는 것, 함께 베스트 프랙티스를 찾아보자고 제안.
    • 페어코딩, 몹코딩
  • 단, 구성원 모두 실무에 적용할 만한 지식과 경험이 필요.
  • 신뢰하는 관계
  1. 상사 설득하기
  • 기술적 완성도가 올라가는 것을 어필.
    • 책: 테스트 주도 개발 실천법과 도구
    • 에러가 의미있는 수치로 줄어들게 됨.
  • 더 정확한 일정: 프로젝트 전체에 대해 좀 더 자세히 들여다보게 됨.
  • 내가 없어도 돌아간다.
    • 이해가 바탕으로 되면 나의 퍼포먼스가 떨어져도 동료가 도와줄 수 있음.
  • 대외적인 팀의 실력 어필
  • 단, 마찬가지로 상사도 실무에 적용할 만한 지식과 경험이 필요.
  • 신뢰하는 관계
  1. 다른 직군 설득하기
  • 버그가 반복되지 않을 것.
    • 같은 이유로 다시 발생하지 않을 것.
    • 다른 곳을 고쳤을 때, 이전 버그가 재발생하지 않을 것.
  • 신뢰하는 관계

여기서 가장 중요한 것은 신뢰!

신뢰 쌓기

  • 오랜 기간 서로 노력해야 함.
  • 일관성있는 솔직한 태도.

신뢰 유지하기

프로젝트 중
  • 끊임없는 커뮤니케이션
  • 중간 공유: 진행 상황 등을 자주 공유하는게 좋음.
평소에
  • 일관성: 컨디션에 따라서 달리지면 안 됨.
  • 인간관계: 부정적인 관계는 만들지 않는 것이 좋음.
  • 거짓말 X: 모르는 것은 인정하고 다시 알아보기.
  • 다른 직군에게도 자세히 설명하기: 자세히 알 수록 공포는 줄어든다. 알아 듣지 못해도 신뢰는 쌓임.

계획하기

  • 가능한 한 자세하게
  • 빼먹지 말 것
  • 계획을 유지하고 지속적으로 업데이트하기
    • 변경되는 기획
    • 예상치 못한 디자인
  • 내 맘 같지 않은 API
    • 중간에 Layer를 따로 두어 API의 변경 사항이 실제 사용되는 코드에 영향을 주지 않게 하는 것이 좋다. 그 중간 Layer만 수정하면 되게끔 하자.

TDD 적용하기

  1. 프로젝트 생성 시 체크박스 체크.
  2. 커맨드 + U 를 누르고 테스트를 실행
    • 시뮬레이터가 실행, 종료되는 과정이 포함되기 때문에 큰 프로젝트의 경우 속도가 느릴 수 있음. 이 때는 host application을 none으로.

상황별 TDD 사용법

레거시 코드

사용자가 오랜 기간 테스트를 했다고 볼 수 있기 때문에 바꾸지 않으면 안정된 상태라고 볼 수 있음.

대신 추가적인 코드에 대해 TDD를 적용하는 것이 바람직함!

서버 API가 있는 경우

응집도와 결합도는 다른 것.

클래스 내의 메서드와 프로퍼티들이 있는데 서로 연관있는 데 꼭 한 곳으로 모일 수는 없는 경우에 ‘응집도가 낮다!’, 그럼에도 분리는 할 수 없다면 ‘결합도는 강하다!’라고 할 수 있음.

DTO(Data Transfer Object)를 두자.

ViewModel -> ServiceLayerProtocol -> NetworkLayerProtocol

Protocol로 연결되어 있기 때문에 Model을 Mock 데이터로 줘도 가능.

라이브러리 테스트

라이브러리가 업데이트가 될 경우에 이미 테스트 케이스는 다 작성되어 있기 때문에 기존에 개발한 기능들이 잘 동작되는지 알 수 있음.

TDD 3단계

  1. 실패하는 테스트
  2. 가장 빨리 성공하게
  3. 리팩토링
    1. 중복을 제거하고: 상수 중복, 의미 중복.
    2. 의미를 드러낸다.(명확하게 한다.)

TDD의 한계

  • 테스트 한 만큼만 보장됨.

다섯 번째: Texture Reactive wrapper 만들고 응용하기

Geektree 님

Texture 란?

UIKit의 부족한 부분을 채워서 만든 라이브러리로 UI를 부드럽고 반응성이 좋게 만들어줌.

UIView 위에 Node를 얹어서 래핑한 것을 사용.

장점

  • Thread Safe
    • 메인 스레드에서 접근하는 경우 크래시가 나도록 함.
  • 무거운 UI 작업을 메인 스레드에서 하지 않도록 함.
  • Constraints의 지옥 탈출과 Layout Specs.
  • Node Wrapper를 사용하여 기존의 View를 그대로 사용할 수 있음.

How to make Reactive Wrapper?

Rx를 사용하는 데에 있어서 한계가 조금 있기 때문에 UIControl 클래스에 대해서 Wrapping해서 써야함.

(뒤의 내용은 너무 어려웠다…)

여섯 번째: 미리보는 Marzipan

구범모 님

Marzipan 이란?

mac OS에서 UIKit 등 iOS 코드를 돌릴 수 있도록 하는 기술.

기존의 iOS 코드를 고칠 필요가 없이 자동으로 mac OS에 맞게 바꿔 준다.

장점

  • mac OS 앱 중 업데이트가 느린 것들이 바로 업데이트가 가능해짐.
  • 수많은 iOS 앱들이 mac OS에서 돌아갈 수 있음.