반응형

[2019.01.29]

원문 : https://medium.com/onfido-tech/reusing-code-with-swift-frameworks-cf60f5fa288a

Swift 프레임워크로 코드 재사용하기(Reusing code with Swift frameworks)

버그를 발견하고 모든 앱을 수정해야 할때, 복사하고 붙여넣기(copy and pasting) 코드는 형편없습니다(sucks). 이를 피하는 방법이 있을까요?

네 바로 그것입니다! 애플은 코드 공유를 쉽게하기 위해 프레임워크(fameworks)라는 도구를 제공합니다. 또한 뿐만아니라(futhermore) 관련된 코드를 그룹화하고(모듈화) 코드 접근을 제한하는(캡슐화) 메커니즘을 제공합니다.

이 글에서 우리는 프레임워크가 무엇이며 왜 사용해야 하는지에 대해 설명할 것입니다. 프레임워크를 생성하고 만드는 방법에 대해 단계별로 가이드할 것이고, 마지막으로는 앱에서 프레임워크를 사용하는 방법을 알아볼것입니다. 프레임워크에 있는 코드는 이 글을 위해서 Swift로 단독으로 작성할 것입니다.

프레임워크란 무엇인가?(What is a framework?)

프레임워크는 공유 코드와 이미지, nibs와 다른 자산(assets)들과 같은 공유 리소스를 포함할수 있는 구조화된 디렉토리 입니다. 코드 및/또는 기타 재사용가능한 자산(assets)을 전달해서 코드가 동작하도록 하는 패키지라고 생각할 수 있습니다.

왜 프레임워크를 사용하나요?(Why use frameworks?)

우리는 프레임워크를 사용해야 하는 주요 이유를 다루었씁니다. 또 다른 좋은 이유는 조직의 서비스와 통합을 쉽게 하기 위함입니다.

예를 들어, Paypal은 앱이 신용카드 트랜잭션을 처리하는데 도움을 주는 프레임워크를 제공합니다. Onfido는 원격으로 신원 검증을 수행하는 프레임워크를 제공합니다.

프레임워크는 서비스와 고객을 통합하는 노력을 줄일수 있습니다. 고객을 위한 시간과 비용이 절약됩니다. 고객이 더 빨리 서비스를 사용할 수록 더 빨리 수익을 올리수 있습니다 💰.

뿐만아니라 시간과 노력은 잠재고객이 공급업체를 선택할때 핵심 요소가 될수 있습니다. 실제로 Stripe는 9.2억 달러가 넘으며, 지물 프로세스의 통합의 불만(frustration)에서 출발했습니다.

프레임워크를 만드는 방법(How to build a framework)

이번 섹션에서 우리는 프레임워크를 생성하고 만드는 과정을 살펴볼것입니다. 그 프레임워크는 간단한 로그인 화면을 포함할 것입니다.

다음 단계로 수행할것입니다:

  1. Cocoa Touch 프레임워크 템플릿을 사용해서 프로젝트를 생성
  2. XIB를 사용해서 뷰 컨트롤러를 추가
  3. 사용자가 로그인 하도록 뷰를 뷰 컨트롤러에 삽입
  4. XIB에 있는 뷰를 LoginViewController 클래스에 연결
  5. 프로그램방식으로 뷰 컨트롤러 불러오기
  6. 프레임워크 외부에서 뷰 컨트롤러 사용하기

이러한 것들이 이미 익숙하면 특정 부분이나 모두 건너 뛸수 있습니다.

1. 프로젝트 생성(Create project)

Xcode에서 메뉴 바에서 File > New > Project…를 선택해서 프레임워크를 생성해 봅시다.

iOS Cocoa Touch Framework 프로젝트 탬플릿을 선택하고 Next를 클릭합니다.

마지막으로 프레임워크에 원하는 이름을 지정할 수 있습니다. MyFramework라는 이름을 줄것입니다. 또한 언어(language)를 Swift로 선택했는지 확인합니다. 이름을 지정하고 Next를 클릭하고 프로젝트를 저장할 위치를 선택하고 마지막으로 Create를 클릭합니다.

이제 비어있는 프레임워크될 프로젝트가 있어야 합니다. 우리 프로젝트에 여러 앱에서 사용할수 있는 화면을 추가합니다.

2. 뷰 컨트롤러 추가하기(Add view controller)

인터페이스 빌더를 사용해서 로그인 화면을 디자인할 비어 있는 XIB 파일을 추가를 계속 합니다. 메뉴 바에서 File > New > File…를 선택하고 Cocoa Touch Class를 선택합니다.

UIViewController의 하위클래스(subclass)로 LoginViewController 클래스 이름을 지정합니다. Also create XIB file 옵션을 클릭합니다. 언어(language)에서 Swift를 선택합니다.

Cocoa Touch Class 템플릿을 사용해서, Xcode는 XIB을 추가하고 Swift 파일 이름을 지정했습니다. XIB에서 뷰 컨트롤러로 필요한 링크를 생성할 것입니다.

3. 뷰 컨트롤러에 뷰 추가하기(Adding views to our view controller)

이 시점에 LoginViewController XIB은 완전히 비어있습니다. 사용자 인증을 위해서 이메일과 비밀번호에 대한 라벨과 텍스트 필드를 추가합니다.

객체 라이브러리를 클릭합니다. 검색바가 나타날때, label을 검색하고 라벨을 비어있는 캔버스로 드래그 앤 드롭합니다.

텍스트 필드에 대해서도 3 단계를 반복합니다.

뷰를 원하는데로 정렬하고 나서 두개의 라벨과 두개의 텍스트 필드를 복사하고 붙여넣습니다(이메일, 비밀번호). Email과 Password*와 같은 의미있는 텍스트로 라벨들을 편집합니다. 마지막으로 사용자가 로그인을 수행하는 버튼을 추가합니다.

이 시점에 사용자가 로그인하는데 필요한 모든것이 제공됩니다. 뷰의 레이아웃과 모양에 대해서 너무 걱정하지 마세요, 그것은 이 글의 범위를 벗어납니다.

4. 뷰를 뷰 컨트롤러에 연결하기(Wiring up the views to the controller)

이번 단계에서 뷰 컨트롤러에서 텍스트를 가져오기 위해서 간단하게 XIB에 있는 이메일과 비밀번호 텍스트 필드 뷰의 링크를 생성할 것입니다. 또한 로그인 버튼의 탭 동작을 로그인 할 수 있는 뷰컨트롤러에 있는 함수와 연결할 것입니다.

우선 LoginViewController.xib을 열고나서 우측 상단에 있는 두개의 교차하는 원 아이콘인 보조 편집기(assistant edit)를 엽니다.

그리고나서 텍스트필드 하나를 선택하고 컨트롤 키(Control key)를 누르고 뷰 컨트롤러에 있는 뷰로 드래그 앤 드롭합니다. XIB와 뷰 컨트롤러 간에 연결 구성을 허용하는 팝업이 열릴것입니다. 이제 텍스트 필드의 connnection을 Outlet으로 설정하고, emailTextField와 같이 각 텍스트 필드에 해당하는 name을 지정하며, type UITextField그리고 마지막에서 아래로 weak를 선택합니다. 비밀번호 텍스트 필드에 대해서도 동일한 단계를 반복합니다.

이제 로그인 버튼을 드래그 앤 드롭하지만, 이 경우에 connection에 대한 Action을 선택하고, 이름은 signIn, 그리고 타입 드롭다운에서 Touch Up Inside를 선택합니다. 이는 약간 다르며, 뷰 자체보다 뷰에 액션을 연결하려하고, 여기에서 로그인 버튼에서 탭에 반응하는 함수를 지정합니다.

이제 콘솔에 사용자이름과 비밀번호를 출력할 것입니다. 로그인 함수안에 다음에 오는 줄을 추가합니다.

print("username \(emailTextField.text) password \(passwordTextField.text)")

사용자가 로그인 하는데 필요한 모든정보를 가지고 있습니다. 여기에서는 인증을 다루지 않고, 코드는 프레임워크 코드와 리소스에 접근하려는 앱을 시연합니다. 프로그래밍적으로 뷰 컨트롤러 로딩할 것이지만 이를 실행하기 전에 뷰 컨트롤러가 어떤 XIB를 로딩했는지 알아야 합니다.

5. 프로그래밍적으로 뷰 컨트롤러 로딩하기(Loading the view controller programatically)

XIB는 뷰의 선언과 이러한 뷰의 구조, 구성, 연결 방법이 포함되어 있습니다. XIB은 누가 어떻게 연결되었는지의 개념(notion)을 가지고 있으며, 하지만 뷰 컨트롤러는 XIB에 대해서 전혀 모르며, 따라서 지금 있는 그대로 뷰 컨트롤러를 인스턴스 할때 뷰 컨트롤러의 뷰와 링크는 생성되지 않습니다. 뷰 컨트롤러가 인스턴스될때 어디에서 뷰를 읽어야하는지 알려줘야 합니다. xib으로부터 읽어온 뷰 컨트롤러에 대해 다음에 오는 사용자정의 초기화 함수를 추가합니다.

init() {
    super.init(nibName: "LoginViewController", bundle: Bundle(for: LoginViewController.self))
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

뷰 컨트롤러를 인스턴스화 하기 위해 init() 함수를 호출할 것입니다. UIViewController은 이미 읽을 XIB(파일의 이름)과 XIB 파일을 찾는 위치를 지정할수 있는 init함수를 포함하고 있습니다; init(nibName:_, bundle:_). XIB 위치의 경우에 LoginViewController 클래스와 같이 동일한 번틀 안에 위치하도록 지정할것입니다.

required init? 함수는 사용하지는 않아 무시하지만, 사용자정의 초기화를 사용할때 뷰 컨트롤러에서 지정해야 합니다.

이제 뷰 컨트롤러를 프로그래밍적으로 로드하는게 가능하지만, 프레임워크 내부에 있는 코드에서만 가능합니다. 우리는 프레임워크를 사용하는 앱에서 뷰 컨트롤러를 초기화하길 원합니다.

6. 프레임워크 외부에서 뷰 컨트롤러 사용하기(Accessing the view controller outside the framework)

Swift는 다른 코드에서 사용할수 있는 코드의 일부를 제한하는 접근 제어(access control)를 가지고 있습니다. 함수와 변수에 대한 접근 제어를 지정하지 않았을때, init()가 internal init()와 동일한것 처럼, Swift는 기본적으로 내부 접근(internal access)를 합니다. 이 경우에 프레임워크에 포함된 모든 코드는 init 함수에서 접근할수 있지만 외부에서는 접근할 수 없습니다. 프레임워크 외부에서 코드에 접근하기 위해 다음에 보이는 init 함수처럼, init 함수 앞에 public 접근 제어 선언을 해야 합니다.

public init() {
    super.init(nibName: "LoginViewController", bundle: Bundle(for: LoginViewController.self))
}

하지만 init함수를 publicly(공개적)으로 사용할수 있도록 해주는게 다가 아닙니다. 지정된 접근제어가 없는 클래스에 존재 init함수는 internal이 됩니다. 우리 클래스에 접근할 수 없는 경우에, 그 안에 있는 init 메소드는 public이 되야 할 것입니다. 이를 해결하기(remedy) 위해서 우리 클래스에 public 접근 제어를 붙여야만 합니다. override 키워드 뒤의 모든 함수에 public을 추가해야 합니다.

public class LoginViewController: UIViewController { ... }

이제 프레임워크를 사용하는 앱에서 뷰 컨트롤러를 초기화할 수 있습니다.

그리고 이게 표준화된 프레임워크 포멧으로 코드와 리소스를 다른 개발자에게 공유하는 방법을 보여주기위해 해야 할 전부입니다.

프레임워크 사용하기(Consiming the framework)

이번 섹션에서 이제 생성할 앱으로 이전 섹션에서 만들었던 프레임워크를 사용할 것입니다 이전 섹션을 건너뛴 경우 여기에서 프레임워크 프로젝트 소스를 구할수 있습니다.

우리는 다음의 것들을 할것입니다

  1. iOS 앱 대상으로 새로운 프로젝트 생성
  2. 뷰 컨트롤러에 로그인 버튼 추가
  3. 버튼을 탭해서 프레임워크 로그인 화면 보여주기

1. 새로운 프로젝트 생성(Create new project)

프레임 워크를 사용하는 앱에 대해 새로운 프로젝트를 만들어 봅니다. 메뉴바에서 File > New > Project…를 선택합니다.

iOS 탭을 찾고 Single View App을 선택하고 Next를 클릭합니다.

Product Name을 MyApp으로 입력합니다. Language는 Swift를 선택합니다. Next를 클릭합니다.

새로운 프로젝트를 저장할 곳을 메시지가 나타날때, 편의를 위해 프레임워크 프로젝트와 동일한 디렉토리에 저장합니다.

2. 로그인 버튼 추가(Add a login button)

Single View App 템플릿의 일부로 자동으로 생성된 뷰 컨트롤러에 버튼을 추가합니다. Main.storyboard를 열고 비어잇는 캔버스에 버튼을 드래그 앤 드롭합니다. 이전에 프레임워크 프로젝트에서 로그인 버튼에 했던것 처럼, 보조 편집기(assistant editor)를 열고 스토리 보드에 있는 ViewController클래스로 버튼을 드래그 앤 드롭합니다. 연결 타입을 Action으로 구성하고, login이름을 주고, type 드롭박스 아래에서 Touch Up Inside를 선택합니다. ViewController 클래스에 다음과 같은 빈 함수가 있어야 합니다.

@IBAction func login(_ sender: Any) {
}

로그인 함수에서 프레임워크에서 로그인 화면을 나타내고자 합니다.

3. 버튼을 탭해서 프레임워크의 로그인 화면 보여주기(Prsent framework login screen on button tap)

이 시점에 우리는 새로운 프로젝트를 생성했으며, 자동으로 생성된 뷰 컨트롤러에 버튼을 추가하고 ViewController 클래스에서 버튼 탭에 대해서 연결되어 잇습니다. 사용자가 로그인 버튼을 누를때 이전에 생성한 프레임워크에서 로그인 화면이 나타나길 원합니다. 하지만 그렇게 하기 전에 프레임워크를 앱에 연결해야 합니다. 프레임워크를 사용할 수 있는 다양한 방법이 있지만, 이 글에서는 Xcode 워크스페이스(workspace)를 사용해서 수행할 것입니다. 작업공간에서 여러개의 프로젝트를 추가하고 단일 프로젝트에 있는 것처럼 서로를 연결합니다.

워크스페이스(workspace)를 생성하기 위해 File > New > Workspace..를 선택하고 이름을 MyApp으로 지정합니다. 앱과 프래임워크 프로젝트와 같은 디렉토리에 저장합니다.

워크스페이스(workspace)는 처음에 비어 있을것이므로 두 프로젝트 모두 워크스페이스에 추가합니다. 메뉴바에서 File > Add File to My App를 선택하고 각각 MyApp과 MyFramework라는 이름의 디렉토리 아래에 있는 MyApp.xcodeproj와 MyFramework.xcodeproj를 추가합니다. 이러한 프로젝트 중에 어떤것도 다른 Xcode창에 열려 있지 않은지 확인합니다.

다음으로 MyApp 프로젝트(프로젝트 탐색기에서 오른쪽 창의 첫번째 탭 아래에 있는 파란색 문서 아이콘) 파일을 선택합니다. 그리고나서 프로젝트 설정 창에서 General탭하고 Embeded binaries 섹션에서 + 버튼을 클릭합니다. 워크스페이스에 있는 모든 옵션을 사용할 수 있는 새로운 윈도우 창이 나타날것입니다. MyFramework.framework를 선택하고 Add를 클릭합니다.

이제 프레임워크가 추가되었으므로 사용자가 로그인 버튼을 탭할때 로그인 화면을 나타낼수 있습니다. ViewController.swift를 열고 import MyFramework를 import UIKit 아래에 추가해서, 우리 파일에서 프레임워크 코드에 접근할 수 있을 것입니다. 다음으로 ViewController 클래스 안의 로그인 함수에 다음에오는 코드 줄을 추가합니다.

present(LoginViewController(), animated: true, completion: nil)

이 줄은 앱에서 사용자가 로그인 버튼을 탭할때 프레임워크로부터 로그인 화면을 나타낼것입니다.

그게 전부입니다! 이제 앱을 실행하고 동작하는 것을 볼수 있습니다!

요약(Summary)

이제 알아야 하는 것입니다.

  • 프레임워크가 무엇인지
  • 왜 프레임워크를 사용하는지
  • 프레임워크를 어떻게 만들고 사용하는지

다음 단계(Next steps)

Xcode 워크스페이스를 사용해서 프레임워크를 사용하는 것은 어렵습니다. 프레임워크를 쉽게 사용할 수 있는 방법이 있을까요?

반응형
Posted by 까칠코더
,