안드로이드 개발자를 위한 스위프트

74
let swift(16) 안드로이드 개발자를 위한 스위프트 Swift & VIPER osxdev.org / todait 유병한

Upload: -

Post on 06-Jan-2017

3.643 views

Category:

Software


0 download

TRANSCRIPT

Page 1: 안드로이드 개발자를 위한 스위프트

let swift(16)

안드로이드�개발자를�위한�스위프트Swift & VIPER

osxdev.org / todait유병한

Page 2: 안드로이드 개발자를 위한 스위프트

저는…

유병한�

현재�투데잇에서�iOS�개발을�담당(하고�있지만�사실은�Android�개발자�🙈🙉)�

이제는�iOS�개발자가�되고픔

Page 3: 안드로이드 개발자를 위한 스위프트

아니�Android�개발자가�왜�iOS�개발을...?

Page 4: 안드로이드 개발자를 위한 스위프트

회사에�iOS�개발자가�없어서...😭

Page 5: 안드로이드 개발자를 위한 스위프트

Agenda

Swift를�사용하면서�Java에�비해�좋았던�부분(중요한�부분만�빠르게�알아봐요!)�

VIPER�아키텍처�적용�사례

Page 6: 안드로이드 개발자를 위한 스위프트

let swift(16)

Android�개발을�하면서�아쉬웠던�부분

Page 7: 안드로이드 개발자를 위한 스위프트

Java ☕

Null�Pointer�Exception�

Getter�/�Setter�

Anonymous�Class�

복잡한�계산로직을�자유자재로,�가독성이�좋게�짜기�힘듦

Page 8: 안드로이드 개발자를 위한 스위프트

Activity (== ViewController)

너무나�많은�역할을�하는�Activity�

View,�Life�Cycle,�Navigation,�Networking,�DB,�Business�Logic,�…�

어떤�코드가�어디에�있는지�찾기�힘듦(==�뭣이�중헌지�모름)�

이러한�구조로는�테스트도�불가능

Page 9: 안드로이드 개발자를 위한 스위프트

빚이되어�돌아오리…💸

Dirty�&�Fast�

모든�것이�빚으로�돌아옴�

버그라던지.�

버그라던지..�

버그라던지...

Page 10: 안드로이드 개발자를 위한 스위프트

인간의욕심은끝이없고

Page 11: 안드로이드 개발자를 위한 스위프트

같은실수를반복한다

Page 12: 안드로이드 개발자를 위한 스위프트

같은�실수를�반복하지�말자!�🤔

Page 13: 안드로이드 개발자를 위한 스위프트

let swift(16)

Swift

Page 14: 안드로이드 개발자를 위한 스위프트

Swift

Optional Type

Property

Closure & Functional

Protocol & Extension

Page 15: 안드로이드 개발자를 위한 스위프트

Java,�넘나�위험한�것!�⚠

Optional Type

Page 16: 안드로이드 개발자를 위한 스위프트

Optional�Type이란?

타입�선언�시�변수에�nil이�저장될�수�있는지�여부를�명시

var nonOptional: Int = 0 nonOptional = nil // Compile Error!

var optional: Int? = 0 optional = nil // OK!

Page 17: 안드로이드 개발자를 위한 스위프트

Optional Chaining

let viewController = UIViewController() print(viewController.navigationItem.backBarButtonItem?.title?.characters.count)

print(viewController.navigationItem.backBarButtonItem?.title ?? "Title")

Page 18: 안드로이드 개발자를 위한 스위프트

Optional Binding - if let

if let viewController = viewController as? UITableViewController { viewController.tableView.reloadData() }

Page 19: 안드로이드 개발자를 위한 스위프트

Optional Binding - if let

if let viewController = viewController as? UITableViewController, refreshControl = viewController.refreshControl { refreshControl.beginRefreshing() }

Page 20: 안드로이드 개발자를 위한 스위프트

Optional Binding - if let

if let viewController = viewController as? UITableViewController, refreshControl = viewController.refreshControl where refreshControl.refreshing { refreshControl.beginRefreshing() }

Page 21: 안드로이드 개발자를 위한 스위프트

Optional Binding - guard let

func signUp1(email: String?) { guard let email = email else { return } print(email.characters.count) }

Page 22: 안드로이드 개발자를 위한 스위프트

Optional Binding - guard let

func signUp(email: String?, password: String?) { guard let email = email, password = password else { return } print("\(email) / \(password)") }

Page 23: 안드로이드 개발자를 위한 스위프트

Optional Binding - guard let

func signUp(email: String?, password: String?) { guard let email = email, password = password where 8 <= password.characters.count else { return } print("\(email) / \(password)") }

Page 24: 안드로이드 개발자를 위한 스위프트

Optional Binding - switch

let passwordText: String? = ""

switch(passwordText) { case .Some(let password) where 8 <= password.characters.count: print(password) case .Some: print("8자리�이상�입력해주세요") case .None: print("password is nil") }

Page 25: 안드로이드 개발자를 위한 스위프트

이제는�안녕�Getter,�Setter�🙋

Property

Page 26: 안드로이드 개발자를 위한 스위프트

Stored Property

struct Box { let width: Double let height: Double let depth: Double }

Page 27: 안드로이드 개발자를 위한 스위프트

Stored Propertystruct Box { var width: Double { willSet { print("newValue: \(newValue)") } didSet { print("oldValue: \(oldValue)") volume = width * height * depth } } var height: Double { ... } var depth: Double { ... } var volume: Double }

Page 28: 안드로이드 개발자를 위한 스위프트

Computed Property

struct Box { var width: Double var height: Double var depth: Double var volume: Double { get { return width * height * depth } set { print("newValue: \(newValue)") } } }

Page 29: 안드로이드 개발자를 위한 스위프트

Computed Property

struct Box { var width: Double var height: Double var depth: Double var volume: Double { return width * height * depth } }

Page 30: 안드로이드 개발자를 위한 스위프트

for,�if의�늪에서�나를�구해줘요!�😱

Closure & Functional

Page 31: 안드로이드 개발자를 위한 스위프트

객체로서의�함수

함수의�인자로�함수를�넘길�수�있음�

함수의�결과로�함수를�반환할�수�있음

Page 32: 안드로이드 개발자를 위한 스위프트

Closure�사용과�타입�추론

Closure는�이름이�없는�함수

var sum = [1, 23, 4, 32].reduce(0, combine: { (sum: Int, element: Int) -> Int in return sum + element })

Page 33: 안드로이드 개발자를 위한 스위프트

Closure�사용과�타입�추론

타입이�명확한�경우�생략�가능

extension SequenceType { /// Returns the result of repeatedly calling `combine` with an /// accumulated value initialized to `initial` and each element of /// `self`, in turn, i.e. return /// `combine(combine(...combine(combine(initial, self[0]), /// self[1]),...self[count-2]), self[count-1])`. @warn_unused_result public func reduce<T>(initial: T, @noescape combine: (T, Self.Generator.Element) throws -> T) rethrows -> T }

var sum = [1, 23, 4, 32].reduce(0, combine: { (sum: Int, element: Int) -> Int in return sum + element })

Page 34: 안드로이드 개발자를 위한 스위프트

Closure�사용과�타입�추론

sum = [1, 23, 4, 32].reduce(0, combine: { sum, element in return sum + element })

sum = [1, 23, 4, 32].reduce(0, combine: { return $0 + $1 })

sum = [1, 23, 4, 32].reduce(0, combine: { $0 + $1 })

sum = [1, 23, 4, 32].reduce(0) { $0 + $1 }

sum = [1, 23, 4, 32].reduce(0, combine: +)

Page 35: 안드로이드 개발자를 위한 스위프트

투데잇에서의�Functional

통계�계산�로직에서�적극적으로�사용�

대용량�데이터를�다루는�것이�아닌�유저�한사람의�데이터�그�중에서도�특정�날짜의�데이터를�주로�다룸�

스레드�처리만�잘�해주면�사용자�체감�상�크게�문제될�상황은�없음�

퍼포먼스도�물론�중요하지만�오류�없고,�가독성이�높고,�수정이�용이한�코드가�필요�

map,�flatMap,�filter,�reduce,�contains�...

Page 36: 안드로이드 개발자를 위한 스위프트

Protocol & Extension

Page 37: 안드로이드 개발자를 위한 스위프트

Property&Method Requirements

Property�&�Method�에�대한�명세

protocol Flyable { var distance: Int { get set } func fly() }

struct SwiftBird: Flyable { var distance: Int func fly() { print("flying!") } }

Page 38: 안드로이드 개발자를 위한 스위프트

Protocol with an Extension

Protocol은�Property를�가질�수�없지만�Method는�가질�수�있음

protocol ViewControllerProtocol: class { var loadingView: LoadingView { get set } }

extension ViewControllerProtocol where Self: UIViewController { func showLoadingView() { loadingView.showLoadingView(self) } func dismissLoadingView() { loadingView.dismissView() } }

Page 39: 안드로이드 개발자를 위한 스위프트

let swift(16)

VIPER

Page 40: 안드로이드 개발자를 위한 스위프트

좋은�Architecture는?

Distribution�

Testability�

Ease�of�Use

Page 41: 안드로이드 개발자를 위한 스위프트

VIPER�구성요소

View Presenter

Router

Interactor Entity

Page 42: 안드로이드 개발자를 위한 스위프트

DataService

Todait의�VIPER�구성요소

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 43: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 44: 안드로이드 개발자를 위한 스위프트

View

UIViewController에�해당�

View�Life�Cycleex)�viewDidLoad�함수가�호출되었음을�Presenter에�알림�

View�Eventex)�signUpButton이�클릭되었음을�Presenter에�알림�

View�Controlex)�titleLabel의�텍스트를�바꾸는�방법을�Presenter에�제공

Page 45: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 46: 안드로이드 개발자를 위한 스위프트

Presenter

View와�Interactor의�중간�다리�역할�

View에�대한�비즈니스�로직�

Life�Cycle에�대한�처리�

View�Event에�대한�처리�

View�업데이트�

UIKit�Independent

Page 47: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 48: 안드로이드 개발자를 위한 스위프트

Interactor

Data(Entity)에�대한�비즈니스�로직

Page 49: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 50: 안드로이드 개발자를 위한 스위프트

Entity

네트워크,�DB�등의�데이터�모델�

Realm�Object,�NSUserDefuatls,�Json�Data�등�

Interactor에서�사용

Page 51: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 52: 안드로이드 개발자를 위한 스위프트

Router

View�간의�전환�

VIPER�컴포넌트들의�DI(Dependency�Injection)를�담당

Page 53: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 54: 안드로이드 개발자를 위한 스위프트

DataService

Network�요청,�DB�접근,�UserDefaults,�이미지�처리�등�반복되는�코드를�모듈화�

Interactor가�호출함

Page 55: 안드로이드 개발자를 위한 스위프트

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 56: 안드로이드 개발자를 위한 스위프트

ViewModel

View에�나타나는�데이터와�1:1�매칭�

Entity가�어떻게�View에�바인딩될지�정의�

Interactor에서�생성되어�Presenter로�전달

Page 57: 안드로이드 개발자를 위한 스위프트

VIPER Flow

가입하기�버튼을�눌려�회원가입을�완료하는�과정

Page 58: 안드로이드 개발자를 위한 스위프트

DataService

presenter.onClickSignUpButton()

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 59: 안드로이드 개발자를 위한 스위프트

DataService

viewController.showLoadingAlert()

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 60: 안드로이드 개발자를 위한 스위프트

DataService

interactor.signUp(signUpViewModel)

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 61: 안드로이드 개발자를 위한 스위프트

DataService

signUpViewModel.checkValidation()

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 62: 안드로이드 개발자를 위한 스위프트

DataServic

serverService.signUp(email, password)

View Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 63: 안드로이드 개발자를 위한 스위프트

realmService.saveUserData()

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 64: 안드로이드 개발자를 위한 스위프트

presenter.onSignUpSucceed() / presenter.onSignUpFailed()

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 65: 안드로이드 개발자를 위한 스위프트

viewController.dismissLoadingAlert()

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 66: 안드로이드 개발자를 위한 스위프트

router.dismissViewController()

DataServiceView Presenter

Router

Interactor

Entity

ViewModel

DataService

Page 67: 안드로이드 개발자를 위한 스위프트

VIPER with Swift - Protocol

protocol ViewControllerProtocol: class { var loadingAlert: LoadingAlert { get set } }

extension ViewControllerProtocol where Self: UIViewController { func showLoadingAlert() { loadingView.showLoadingAlert(self) } func dismissLoadingAlert() { loadingView.dismissAlert() } }

Page 68: 안드로이드 개발자를 위한 스위프트

VIPER with Swift - Computed Property

protocol SignUpViewControllerProtocolForPresenter: class { var email: String? { get set } var password: String? { get set } }

extension SignUpViewController: SignUpViewControllerProtocolForPresenter { var email: String? { get { return emailTextField.text } set { emailTextField.text = newValue } } var password: String? { get { return passwordTextField.text } set { passwordTextField.text = newValue } } }

Page 69: 안드로이드 개발자를 위한 스위프트

장점

하나의�화면에서�기능�단위로�코드를�명확하게�분리�

(물론�모든�컴포넌트에�대해�테스트를�하고�있지�않지만)�모든�컴포넌트에�대해�테스트�가능해지는�구조가됨�

(물론�혼자�개발하고�있지만)�분업이�훨씬�수월해짐

Page 70: 안드로이드 개발자를 위한 스위프트

단점

간단한�화면,�간단한�기능에�대해서도�작성해야할�코드가�늘어남

Page 71: 안드로이드 개발자를 위한 스위프트

Next Step

Code�Generator�

RxSwift,�KVO�

Android에도�적용

Page 72: 안드로이드 개발자를 위한 스위프트

Swift로�iOS�앱�개발을�하면서�느낀�점

Swift�정말�최고!�

UI가�있는�어플리케이션�만든다는�관점에서�큰�동작�원리는�Android나�iOS나�비슷한�것�같음�

iOS에도�문제가�많다고�하지만�안드로이드에�비할바는�아닌�것�같음�

훨씬�평화로운�iOS!�피쓰~�🕊

Page 73: 안드로이드 개발자를 위한 스위프트

투데잇의 성장을 함께할 당신을 기다리고 있습니다.

i O S 개 발 을 박 ♥ 살 내 주 실 당 신 !

Page 74: 안드로이드 개발자를 위한 스위프트

let swift(16)