Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions Documents/ko_KR/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ targets: [

## Basics

의존성 주입(Dependency Injection, 이하 DI로 표기)을 사용하는 주요 이유는 별도의 [문서](/WHY_DI.md)에 설명되어 있습니다. 당신의 앱이 DI의 혜택을 받을 수 있는지 확실하지 않은 경우 계속하기 전에 이 내용을 읽어보십시오.
의존성 주입(Dependency Injection, 이하 DI로 표기)을 사용하는 주요 이유는 별도의 [문서](./WHY_DI.md)에 설명되어 있습니다. 당신의 앱이 DI의 혜택을 받을 수 있는지 확실하지 않은 경우 계속하기 전에 이 내용을 읽어보십시오.

## 핵심 요소

Expand Down Expand Up @@ -70,7 +70,7 @@ class LoggedInComponent: Component<LoggedInDependency> {

예제의 `shared` 구문은 저희가 (`Component` 기본 클래스 내부에서) 제공하는 유틸리티 함수로 이 `var`에 액세스할 때마다 단순하게 동일한 인스턴스를 반환합니다. (아래에 선언된 프로퍼티는 대조적으로 새로운 매번 인스턴스를 반환합니다). 이렇게 하면 이 프로퍼티의 라이프사이클이 Component의 라이프사이클에 연결됩니다.

Component를 사용하여 이 component와 쌍을 이루는 `ViewController`를 구성할 수도 있습니다. 위의 예제에서 볼 수 있듯이, 이것은 `ViewController`가 프로젝트에서 DI 시스템을 사용하고 있다는 사실을 모르고도 `ViewController`가 필요로 하는 모든 의존성을 전달할 수 있도록 합니다. **"DI의 이점"** 문서에서 언급했듯이 구체적인 클래스나 구조체 대신 프로토콜을 전달하는 것이 가장 좋습니다.
Component를 사용하여 이 component와 쌍을 이루는 `ViewController`를 구성할 수도 있습니다. 위의 예제에서 볼 수 있듯이, 이것은 `ViewController`가 프로젝트에서 DI 시스템을 사용하고 있다는 사실을 모르고도 `ViewController`가 필요로 하는 모든 의존성을 전달할 수 있도록 합니다. [**"DI의 이점"**](./WHY_DI.md) 문서에서 언급했듯이 구체적인 클래스나 구조체 대신 프로토콜을 전달하는 것이 가장 좋습니다.

# Dependencies

Expand All @@ -87,6 +87,28 @@ protocol LoggedInDependency: Dependency {
}
```

## Dynamic dependencies

동적 의존성은 런타임에 얻은 의존성을 나타냅니다. 좋은 예는 AuthenticatedUser 객체입니다. User 객체가 항상 존재하는 것은 아닙니다. 사용자가 로그인한 후에만 존재합니다. 앱에 로그아웃 및 로그인 `Scope`가 있다고 가정하면 이 User 객체는 로그인 `Scope`와 하위 `Scope` 내에서만 사용할 수 있어야 합니다. 생성자 주입을 통해 로그인 `Scope`에 AuthenticatedUser 객체를 제공하는 한 가지 방법은 다음과 같습니다:
```
class LoggedInComponent: Component {
let user: AuthenticatedUser
init(parent: Scope, user: AuthenticatedUser) {
self.user = user
super.init(parent: Parent)
}
}
```

그런 다음 로그인 `Scope`의 상위 `Scope`에서 일반적으로 사용하는 computed `var` 대신 메소드를 통해 `LoggedInComponent`를 인스턴스화할 수 있습니다:
```
class RootComponent: Component {
func loggedInComponent(user: AuthenticatedUser) {
return LoggedInComponent(parent: self, user: user)
}
}
```

# Component 사용하기

좋은 점은 Needle command-line 코드 제너레이터를 실행할 준비가 되지 않았더라도 코드를 작성하고 컴파일할 준비가 되었다는 것입니다. 우리는 또한 `imageCache`와 `networkService`가 어느 상위 `Component`에서 왔는지 시스템에 알리지 않았습니다.
Expand Down
2 changes: 1 addition & 1 deletion Documents/ko_KR/GENERATOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ brew install needle
Needle의 제너레이터는 명령줄에서 호출할 수 있지만 빌드 시스템과 직접 통합될 때 가장 편리합니다. Uber에서는 CI 빌드에 [BUCK](https://buckbuild.com/)를 사용하고 로컬 개발에 Xcode를 사용합니다. 따라서 우리에게 Needle은 BUCK와 통합됩니다. 그런 다음 Xcode가 코드 생성을 위해 BUCK Needle 대상을 호출하도록 합니다. 대부분의 Swift 애플리케이션이 Xcode를 빌드 시스템으로 사용하기 때문에 여기서는 이를 다룰 것입니다.

1. [Releases page](https://github.com/uber/needle/releases)에서 수동으로 다운로드 혹은 [Carthage](https://github.com/Carthage/Carthage) 또는 [Homebrew](https://github.com/Homebrew/brew)를 사용하여 최신 제너레이터 바이너리를 다운로드 하십시오.
2. Xcode에서 앱의 executable target's의 "Build Phases" 섹션의 "Run Script"를 추가합니다. ![](Images/build_phases.jpeg)
2. Xcode에서 앱의 executable target's의 "Build Phases" 섹션의 "Run Script"를 추가합니다. ![](https://raw.githubusercontent.com/uber/needle/master/Images/build_phases.jpeg)
3. "Shell"의 값이 `/bin/sh`으로 되어 있는지 확인합니다.
4. 스크립트 입력란에 제너레이터를 호출하는 shell script를 추가합니다. 예를 들어 샘플 TicTacToe 앱은 다음 스크립트를 사용합니다.
`export SOURCEKIT_LOGGING=0 && ../Carthage/Checkouts/needle/Generator/bin/needle generate Sources/NeedleGenerated.swift Sources/ --header-doc ../../copyright_header.txt`.
Expand Down
2 changes: 1 addition & 1 deletion Documents/ko_KR/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ![](Images/logo.png)
# ![](https://raw.githubusercontent.com/uber/needle/master/Images/logo.png)

[![Build Status](https://travis-ci.com/uber/needle.svg?branch=master)](https://travis-ci.com/uber/needle?branch=master)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
Expand Down
4 changes: 2 additions & 2 deletions Documents/ko_KR/WHY_DI.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

## 설명하기 위한 다소 현실적인 예

패턴을 추상적인 용어로 설명하는 대신 간단한 뷰 컨트롤러 기반 예를 사용하여 패턴을 이해해 보겠습니다. 추상적인 설명에 관심이 있으시면 Wikipedia에는 [훌륭한 기사](https://en.wikipedia.org/wiki/Dependency_injection) 있습니다.
패턴을 추상적인 용어로 설명하는 대신 간단한 뷰 컨트롤러 기반 예를 사용하여 패턴을 이해해 보겠습니다. 추상적인 설명에 관심이 있으시면 Wikipedia에는 [훌륭한 ](https://en.wikipedia.org/wiki/Dependency_injection) 있습니다.

서버에서 검색한 사진 세트를 표시하는 ViewController가 있는 사진 검색 앱을 개발 중이라고 가정해 보겠습니다. 이 매우 간단한 앱에는 사진을 표시하는 `PhotosViewController`와 서버에서 사진을 요청하는 로직를 캡슐화하는 `PhotosService`가 있습니다. `PhotosViewController`는 보기 로직을 구현하고 `PhotosService`는 HTTP 요청 전송 및 응답 분석 로직을 포함합니다. DI를 사용하지 않으면 `PhotosViewController`는 `init` 또는 `viewDidLoad` 메소드에서 `PhotosService`의 새 인스턴스를 인스턴스화 합니다. 그런 다음 서비스 객체를 사용하여 적합하다고 판단될 때 사진을 요청할 수 있습니다.
서버에서 검색한 사진 세트를 표시하는 ViewController가 있는 사진 검색 앱을 개발 중이라고 가정해 보겠습니다. 이 매우 간단한 앱에는 사진을 표시하는 `PhotosViewController`와 서버에서 사진을 요청하는 로직를 캡슐화하는 `PhotosService`가 있습니다. `PhotosViewController`는 로직을 구현하고 `PhotosService`는 HTTP 요청 전송 및 응답 분석 로직을 포함합니다. DI를 사용하지 않으면 `PhotosViewController`는 `init` 또는 `viewDidLoad` 메소드에서 `PhotosService`의 새 인스턴스를 인스턴스화 합니다. 그런 다음 서비스 객체를 사용하여 적합하다고 판단될 때 사진을 요청할 수 있습니다.

이제 한 번 코드를 분석해 보겠습니다. 현재 상태에서는 `PhotosViewController`와 `PhotosService`가 밀접하게 결합되어 있습니다. 여기에는 몇 가지 문제가 있습니다.
1. `PhotosViewController`도 변경하지 않고는 `PhotosService`를 변경할 수 없습니다. 두 개의 클래스만 있으면 괜찮아 보일 수 있지만 수백 개의 클래스가 있는 실제 시나리오에서는 앱 개발 속도가 크게 느려집니다.
Expand Down