Written by
Amy
on
on
Dev Seminar 2018
Dev Seminar, 2018 리뷰
- 일시: 2018년 3월 25일 일요일, 10시 ~ 19시 (9시간)
- 장소: 역삼 마루 180
RxSwift
키워드
비동기 처리,반응형 프로그래밍observable,binding,subscribe반응형 프로그래밍은약속이다. 내가 때마다 계속 말하지 않아도 (내가 매줄 코딩하지 않아도) 이런 이벤트가 발생되는 상황에서는 이렇게 하자고 “약속”한 것에 대해 제대로 반응해주는 것!- 강사님의 RxSwift와의 첫 만남: 카테고리 API 와 리스트 API → 두 가지 API 콜을 조인해서 써야했던 경우에 Rx를 도입하게 됨
실습
// 가장 인상 깊었던 코드 조각...🙏🏻
func bind() {
addButton.rx.tap.asObservable()
.flatMap { [weak self] _ in
ColorViewController.rx.create(parent: self)
.flatMap({ (cv: ColorViewController) -> Observable<UIColor> in
cv.rx.selectedColor
}).take(1) //take(1) 하면 observable이 complete 됨
}.subscribe(onNext: { [weak self] (color: UIColor) in
guard let `self` = self else { return }
var colors = self.dataSource.value
colors.append(color)
self.dataSource.accept(colors)
}).disposed(by: disposeBag)
dataSource.bind(to: self.collectionView.rx.items(cellIdentifier: "colorCell", cellType: UICollectionViewCell.self)) { (index, color, cell) in
cell.contentView.backgroundColor = color
}.disposed(by: disposeBag)
collectionView.rx.itemSelected.asObservable()
.subscribe(onNext: { [weak self] (indexPath) in
guard let `self` = self else { return }
var colors = self.dataSource.value
colors.remove(at: indexPath.item)
self.dataSource.accept(colors)
}).disposed(by: disposeBag)
}
오토레이아웃
오토레이아웃 디버깅
🧐 View 에 이름 붙여서 찾아내기
- ✳︎
Identity Inspector에서Accessibility에Identifier를 설정해놓으면 오토레이아웃 오류로 인해 디버깅 될 때 해당 아이덴티파이어 이름을 달고 디버거 콘솔에 출력 된다.
🧐 레이아웃 비주얼 디버거에서 포인터 주소로 검색하기
- ✳︎ Layout Debugger에서 포인터 주소로 뷰나 NSLayoutConstraint를 검색할 수 있다.
🧐 symbolic breakpoint로 오토레이아웃 오류 시점에 앱 죽이기
- ✳︎
symbolic breakpoint를 활용한 오토레이아웃 디버깅: 브레이크포인트의 심볼로UIViewAlertForUnsatisfiableConstraints를 추가하면 해당 시점에서 브레이크포인트가 걸린다. 이 때 아래 방식으로 lldb 고고!
po $r15
< UIView: 0x7f910ef169f0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x60400022e2e0>>
po $rbx
< __NSArrayM 0x600000252510>(
< NSLayoutConstraint:0x60400028a5a0 UIView:0x7f910ec003d0.width == 150 (active)>,
< NSAutoresizingMaskLayoutConstraint:0x60000028f3c0 h=--& v=--& UIView:0x7f910ec003d0.width == 100 (active)>
)
po $r14
po [[UIWindow KeyWindow] autolayoutTrace]
오토레이아웃 오픈소스
실습
TDD
Test Coverage
- 전체 유효한 코드 대비 테스트가 커버한 비율
목표
- ViewController에 대해 테스트 비율을 100%로 만드는 것
- Given: 주어진 상황에서
- When: 이러한 조건일 때 실행된다면
- Then: 성공하는가 실패하는가 (검증)
단축키
cmd Ucmd shift Ucmd shift ,스키마 설정ctrl option cmd U해당 함수만 테스트 실행
iOS Runtime Header
실습
// 가장 인상 깊었던 코드 조각...🙏🏻
func testJoinButton_push() {
//Given
let navi = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as! UINavigationController
let viewController = navi.topViewController as! LoginViewController
UIApplication.shared.keyWindow?.rootViewController = navi
//When
_ = viewController.view // load view
print(viewController.value(forKey: "storyboardSegueTemplates"))
let segueTemplates = viewController.value(forKey: "storyboardSegueTemplates") as? [AnyObject]
let template = segueTemplates?.first as? AnyObject
let targetActions = viewController.joinButton.value(forKey: "_targetActions") as? [AnyObject]
let buttonTarget = targetActions?.first?.value(forKey: "_target") as? AnyObject
print(targetActions)
//XCTAssert(NSStringFromClass(type(of: template!))) ===
XCTAssert(template === buttonTarget)
viewController.joinButton.sendActions(for: .touchUpInside)
//Wait
let expectation = XCTestExpectation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: expectation.fulfill
)
XCTWaiter().wait(for: [expectation], timeout: 1)
//Then
XCTAssertEqual(navi.viewControllers.count, 2)
XCTAssertEqual(navi.topViewController?.title, "Create Account")
}
func testWelcomeLabel_displayUsernameWhenFetchError() {
//GIVEN
let storyboard = UIStoryboard(name: "Profile", bundle: nil)
let navi = storyboard.instantiateInitialViewController() as? UINavigationController
let viewController = navi?.topViewController as! ProfileViewController
let userService = StubUserService()
userService.stubbedResult = .failure(NSError())
viewController.userService = userService
//WHEN
_ = viewController.view // load view
//THEN
XCTAssertEqual(viewController.welcomeLabel.text, "Error!")
//XCTAssertEqual(viewController.welcomeLabel.text?.lowercased(), "error")
//XCTAssrt(viewController.priceLabel.text.contains("1,342")
}