2019년 1월 23일 수요일

Swift By Sundell - Basics

https://www.swiftbysundell.com/basics

- Unit Testing

Xcode에 포함되어 있는 XCTest를 사용한다.

import XCTestCase

class는 XCTestCase를 상혹하고 함수 이름을 test로 시작하게 짓는다.

함수의 내용은 Given - When - Then 의 형태로 구현한다.
"Given these conditions when these actions are performed, then this is the expected outcome"

Given이 중복되는 경우 setUp() 함수를 사용한다.
setUp: 테스트 실행시 항상 먼저 실행되는 함수

- Grand Central Dispatch

GCD: "a different queue of execution"을 통해 asynchronous하게 code가 실행되도록 한다.
DispatchQueue.main
DispatchQueue.global

qos, attributes 등의 속성을 정해줄 수 있다.

- Layout Anchors

Auto layout을 편하게 지정하게 해준다. iOS9에서 새로 소개되었다.

UIView: "a series of anchors"를 포함하고 있다.

anchor를 지정하고 나면 항상 활성화를 해주어야 한다. 다음의 두가지중 한가지 방법을 사용한다.

1. constraint.isActive를 true로 설정
2. NSLayoutConstraint.activate([constraint])

고려해 봐야 할 점 세가지

1. 기본적으로 모든 view는 initial auto resizing mask를 layout constraints로 바꾼다. 이걸 disable하고 싶으면 setTranslatesAutoresizingMaskIntoConstraints를 false로 설정한다.
2. 여러 view로부터의 anchor를 사용하려면 모두가 같은 view hierarchy에 속해 있어야 한다.
3. constraint can be dynamically enabled and disabled. 이러한 경우 constraint를 add/remove 하기 보다는 isActive를 사용하는 것이 낫다.

- Child View Controllers

1. Parent에 add하기

parent.view.addSubView
parent.addChild
child.didMode

2. Parent에서 remove 하기

child.willMode
child.removeFromParent
child.view.removeFromSuperview

=> 항상 3개의 함수를 호출해 주어야 하므로 extension으로 add/remove 함수를 만들어서 사용하면 편할 것이다.

3. UI를 만들 때 Child view controller로 만들면 유용한 점이 있다.

- viewDidLoad나 viewWillAppear 같은 event를 받아서 처리할 수 있다.
- UI와 UI에 관련된 로직을 한군데에 포함함으로서 하나의 단위로 사용될 수 있다.
- View controller는 child로 추가되면 화면 전체를 차지하게 된다. 따라서, 별도로 full screen UI를 위한 layout code를 만들지 않아도 된다.
- 여러곳에서 사용될 수 있게 된다. Navigation Controller에 push 된다던가, child로 embedd 된다던가.

- Codable

Codable은 단순히 Encodable과 Decodable의 type alias이다.

typealias Codable = Decodable & Encodable

예를 들어 struct User가 Codable를 상속받으면 JSONEncode를 사용해서 쉽게 JSON으로 encoding할 수 있다.

struct User: Codable { ... }

let data = try JSONEncoder().encode(user)
let data2 = try JSONDecoder().decode(User.self, from: data)

그런데 json 포맷이 안맞으면 어떻게 해야 할까?
- 변수 이름을 포맷에 맞출까?

json 포맷에 맞는 struct를 만들어 decoding을 한 후 다시 내가 사용하는 struct로 변환한다.

snake case와 camel case가 안맞는 경우 keyDecodingStrategy를 지정해 주면 된다.

decoder.keyDecodingStrategy = .convertToSnakeCase


Building asynchronous views in SwiftUI 정리

Handling loading states within SwiftUI views self loading views View model 사용하기 Combine을 사용한 AnyPublisher Making SwiftUI views refreshable r...