이 글은 iOS 개발환경을 구축하기 위해 알아야 할 사항을 가이드하는 문서입니다.
1. 개발 시작전에 알아둘 내용 (이전글)
2. 개발 환경 소개
✔︎ 엑스코드(Xcode)
Xcode는 애플의 macOS와 iOS 앱을 개발하기 위한 IDE(통합 개발 환경) 애플리케이션의 이름이기도 하지만, 포괄적인 의미에서 애플의 개발 환경 전체를 지칭하기도 한다. 애플 개발자 사이트나 맥 앱스토어에서 Xcode 앱을 다운받아서 설치하면 GUI 기반 개발 도구 뿐만 아니라, 터미널을 실행하고 들어가야만 확인하고 사용할 수 있는 UNIX 기반의 개발 도구들이 함께 설치된다. 겉으로 드러나는 개발 환경은 Xcode 뿐이지만 그 밑에 주춧돌처럼 지행해주는 구성 요소들은 UNIX 개발 환경을 모두 포함하고 있다. macOS나 iOS 모두 UNIX 시스템 — 정확히는 Darwin 이라는 FreeBSD 시스템에 기반을 두고 있기 때문이다. 그렇기 때문에 UNIX 나 Linux 명령어 기반의 개발 환경에 익숙한 개발자들은 Xcode 자체는 모르더라도 이미 Xcode의 내부 시스템은 알고 있는 것이나 다름없다.
설치하기
Xcode 정식 버전 앱은 항상 맥 앱 스토어에서 배포하고 있다. macOS에 있는 맥 앱 스토어를 실행하고 우측 상단 검색창에 Xcode를 입력하거나 Developer Tool 카테고리에 가면 최신 버전의 Xcode를 다운로드할 수 있다. 새로운 버전이 나오면 상단의 Updates 탭에서 최신 버전으로 업데이트하면 된다.
Xcode 7.1을 기준으로 앱의 용량은 4.3GB 정도 되기 때문에 설치를 하기 전에 압축 파일을 다운받으려면 8GB 이상 여유 공간이 있어야만 한다. 그렇지 않으면 다운로드만 되고 설치가 불가능할 수도 있다. 처음 설치하면 추가적인 커맨드 명령 모음이나 그래픽 도구 등을 다운로드해야 하기 때문에 좀 더 여유공간이 있는게 좋다.
전체 화면 구성
Xcode를 실행하고 프로젝트를 생성하면 기본적으로 보이는 화면을 살펴보자. 크게 좌측 — 내비게이터 영역, 가운데 — 편집기 영역, 우측 — 유틸리티 영역으로 나뉜다.
좌측 영역은 프로젝트 내비게이터 영역으로 프로젝트와 관련된 파일, 클래스, 찾기, 경고, 테스트, 디버그, 브레이크포인터, 로그 탭을 선택할 수 있다. 가운데 넓은 영역은 편집 영역으로 좌측의 프로젝트 파일 중에 어떤 형태를 선택하느냐에 따라 프로젝트 정보를 표시하기도 하고, 소스 코드를 표시하기도 한다. 만약 스토리보드나 XIB 같은 인터페이스 빌더 파일을 선택하면 화면을 직접 보고 디자인할 수 있는 인터페이스 빌더 화면을 표시한다. 화면 우측은 유틸리티 영역으로 선택할 파일명, 경로부터 도움말, 속성, 크기, 연결 정보등을 세부적으로 조작할 수 있다. 특히 앱의 프로토타입을 제작하거나 화면 설계를 할 때 많이 활용하게 된다.
화면 상단 좌측에는 실행과 멈춤 조작을 하는 관리 부분과 프로젝트 일부 중에 어떤 타깃을 어느 디바이스 목표에 맞춰서 실행할 것인지 선택하는 영역이 존재한다. 화면 상단 우측에는 앞서 설명한 프로젝트 영역이나 유틸리티 영역, 그리고 화면에는 보이지 않지만 디버깅 중에 나타나는 디버깅 콘솔 영역을 표시하거나 감추는 동작을 선택할 수 있다.
내비게이터 영역
- 프로젝트 내비게이터 : 프로젝트에 포함된 소스나 리소스, 프레임워크 파일들을 살펴보고 확인할 때 사용한다. 프로젝트 내비게이터에서 어떤 파일을 선택하느냐에 따라서 화면 중앙의 편집기 영역과 우측의 유틸리티 영역은 각기 다른 화면이 나타난다.
- 심벌 내비게이터 : 프로젝트에서 사용하는 클래스(C)나 구조체(S), 메서드(M)의 심벌을 구조적으로 확인할 수 있다. 심벌 내비게이터 하단에는 필터바가 있어서, 원하는 종류의 심벌만 선택해서 볼 수 있다.
- 검색 내비게이터 : 프로젝트나 워크스페이스 전체에서 입력한 값을 검색할 때 사용한다. 찾기(Find)와 바꾸기(Replace) 기능을 선택할 수 있고, 정규표현식 같은 고급 검색 기능을 활용할 수 있다.
- 이슈 내비게이터 : 프로젝트 빌드 중에 경고나 에러 같은 이슈들을 모아서 보여주는 화면이다. 이슈를 파일별(By File)로 정렬하거나 이슈 종류별(By Type)로 정렬할 수도 있다.
- 테스트 내비게이터 : 프로젝트에 유닛 테스트나 UI 테스트가 포함되어 있는 경우에 전체 유닛 테스트나 개별 유닛 테스트를 수행할 때 사용한다.
- 디버그 내비게이터 : 디버그 모드에서만 활성화 되고, 쓰레드별 또는 GCD 큐별로 동작 중인 스택 정보를 확인할 수 있다. CPU, 메모리, 디스크, 네트워크 사용율 변화에 대해서도 모니터링하는 기능을 제공한다.
- 브레이크포인터 내비네이터 : 코드별로 설정한 브레이크 포인트 목록을 관리할 수 있다. Xcode에서는 북마크 대신 브레이크 포인터를 활용하기 때문에 자주 사용하는 화면이다.
- 로그 내비네이터 : 빌드 결과나 실행 결과 등 콘솔에 찍히는 모든 출력 결과를 로그로 저장하는 화면이다.
유틸리티 영역 — 인스펙터(Inspector)
- 파일 인스펙터 : 프로젝트 내비게이터에서 선택한 파일에 대한 파일명과 종류를 보여주는 Identity and Type 항목과 인코딩, 줄바꿈 문자 속성 등을 관리하는 Text Settings 항목을 표시한다. 파일명을 변경할 때 파일 인스펙터에서 변경하면 된다.
- 도움말 인스펙터 : 선택한 파일에 대한 간편한 도움말을 제공한다. 만약 특정 클래스를 포함하는 소스 파일이라면, 클래스 레퍼런스 도움말의 요약 화면을 보여주며, 이와 관련된 라이브러리 문서나 샘플 코드에 대한 링크도 제공한다.
- 아이덴티티 인스펙터 : 세 번째 항목인 아이덴티티 인스펙터부터 여섯 번째인 연결 인스펙터까지는 프로젝트 내비게이터에서 XIB나 스토리보드(storyboard) 리소스 파일을 선택했을 경우에만 보여진다. 아이덴티티 항목은 선택한 뷰 요소에 대한 커스텀 클래스를 지정하거나, Object ID 등 뷰 고유한 값을 지정할 때 사용한다.
- 속성 인스펙터 : 선택한 뷰 요소의 세부적인 속성을 변경할 때 사용한다. UITableView나 UIScrollView처럼 뷰 클래스를 상속받은 클래스라면 상위 클래스의 속성까지 바꿀 수도 있다.
- 크기 인스펙터 : 선택한 뷰 요소의 화면에서 위치와 크기를 조절하기 위해 사용한다. 기본적으로 좌표는 int타입이 아니라 float타입으로 사용하며, iOS의 경우 원점좌표계에서 4사분면을 사용하기 때문에 좌측상단이 원점이다.
- 연결 인스펙터 : 화면을 구성하는 뷰 객체와 코드의 아웃렛 연결 상태를 확인하거나 새롭게 연결할 때 사용한다.
유틸리티 영역 — 라이브러리(Library)
- 템플릿 라이브러리 : 파일 메뉴에서 New..를 선택해서 만들 수 있는 모든 파일들을 포함해서, 템플릿 선택 화면을 띄우지 않고 드래그 앤 드롭으로 새로운 파일을 생성할 수 있다. 전체 화면 모드에서는 메뉴가 감춰지기 때문에 종종 템플릿 라이브러리가 쓸모가 있다.
- 코드 조각 라이브러리 : 코드를 작성할 때 자주 사용하는 관용적인 코드 문구를 저장해놓고 쉽게 꺼내서 쓸 수 있다. 미리 지정된 코드 조각이 아니더라도, 자신만의 코드 스타일을 등록해놓고 쓸 수 있다.
- 객체 라이브러리 : 인터페이스 뷰 디자인 작업을 할 때 사용하는 화면으로 원하는 뷰 요소를 선택해서 드래그 앤 드롭으로 인터페이스 영역에 가져다가 작업을 한다.
- 미디어 라이브러리 : 시스템 수준의 공통 미디어와 프로젝트 수준의 미디어를 확인하는 용도로 사용한다.
프로젝트 템플릿
Xcode에서는 새 프로젝트를 만들 때 자주 사용하는 프로젝트 템플릿을 제공한다. Master-Detail Application은 일반적인 형태로 목록이 나오고 그 중에 하나를 선택하면 세부 정보가 표시되는 마스터-디테일 형태 앱을 만들 때 사용한다. Page-based Application은 전자책과 비슷한 형태로 콘텐츠를 페이지 단위로 넘기면서 보는 앱을 만들 때 사용한다. Single View Application은 기본적으로 뷰 컨트롤러와 뷰가 하나씩 존재하는 형태로, 처음 시작할 때 가장 많이 사용하는 템플릿이다. Tabbed Application은 화면 아래쪽에 화면 전환을 위한 탭이 들어간 앱을 만들 때 사용한다. Game 템플릿은 OpenGL ES나 Metal 기반 앱을 만들 때 사용한다. Cocoa Touch Framework는 iOS용 공유할 동적 라이브러리를 만들 때 사용하고, Cocoa Touch Static Library는 정적 라이브러리를 만들 때 사용한다. Xcode 버전이 올라갈 때마다, 프레임워크 사용방법에 따라 프로젝트 템플릿 코드도 함께 바뀌기 때문에 같이 살펴보는 것을 권장한다.
인터페이스 리소스와 UIKit Catalog
- 인터페이스 빌더로 디자인한 결과는 NeXT Interface Builder의 머릿 글자에서 따온 NIB파일로 저장한다. Xcode3부터는 XML기반으로 인터페이스 빌더 코코아 도큐멘트 포맷인 XIB 형식을 지원하고 있는데 그 내용은 NIB 타입과 동일하다. XML 기반으로 사용하는 이유는 대부분 개발 환경에서 소스 관리 도구를 사용할 수 있기 때문이다.
- 스토리보드(Storyboard)는 화면 단위로 설계하던 XIB 방식에서 발전한 형태다. 전체 화면들을 모아서 말그대로 스토리보드처럼 화면의 전환과 흐름을 볼 수 있도록 화면 리소스를 모아놓은 형태로, 실제 파일 내부 구조는 XIB 형식을 내부적으로 개선한 XML 파일 형식이다. Xcode7부터는 Storyboard Reference 기능을 지원하고 있어서, 보다 큰 스토리보드 작업을 할 때 파일 단위로 나눠서 작업할 수도 있다.
- 스토리보드나 XIB를 하나의 프로젝트에서 혼용해서 사용하는 것도 전혀 상관없다. 프로젝트 템플릿에서 만들어지는 코드는 스토리보드를 우선적으로 사용하도록 권장하고 있지만, 화면별로 XIB로 화면을 설계하고 처리해도 잘 동작한다.
- UIKit Catalog 샘플 : 인터페이스 빌더로 화면 디자인 작업을 처음 해본다면, 아이폰용 UI 콘트롤 객체들을 한꺼번에 다루는 UICatalog 라는 예제를 살펴보기를 권장한다. 이 예제에는 물론 MainMenu.xib 라는 리소스 파일이 있지만 이것은 Navigation-based 앱을 만들 때 생기는 최소의 뷰 컨트롤러 리소스만 있을 뿐이다. 나머지 화면에 표시되는 모든 UIKit 객체들은 각각의 뷰 컨트롤러가 직접 코드로 런타임에 생성하기 때문에, 처음에 공부할 때 도움이 많이 될 것이다. 개발자 라이브러리 중에 애플이 만든 샘플 코드를 살펴보는 것은 API 사용방법을 살펴보고 배우는 데 필수 항목이다.
✔︎ 프로젝트 관리
프로젝트와 워크스페이스
- 프로젝트(xcodeproj) : 제품을 만들기 위한 모든 파일과 리소스, 정보를 포함하는 저장소를 말한다. 라이브러리와 프레임워크, 프로젝트 수준의 빌드 환경과 타깃별 소스와 빌드 환경을 포함한다.
- 워크스페이스(xcworkspace) : 여러 프로젝트와 관련 문서를 한꺼번에 묶어서 관리하는 단위로, 프로젝트 하나만 다룰 경우 일부러 만들지 않아도 상관없다. 특히 프로젝트 템플릿으로 새 프로젝트를 시작하는 경우에는 내부적으로 숨겨진 워크스페이스가 생성된다.
프로젝트와 타깃 구조
프로젝트에는 빌드하기 위한 여러 환경 설정을 포함하는 내부 데이터 구조가 필요하다. 프로젝트에서 빌드 동작 단위는 타깃별로 동작한다.
- 프로젝트 : MyProject.xcodeproj 가 서버용, 클라이언트용, 공통 라이브러리 타깃을 포함하고 있음.
- 타깃 : MyClientApp, MyServerApp, MyLib 각기 다른 타깃이 존재함.
- 제품 : 각 타깃별로 MyClient.app, MyServer.app, MyLib.framework 제품을 빌드해서 생성함
빌드 환경과 빌드 설정
- 타깃별로 빌드 과정에서 필요한 빌드 환경, 빌드 단계, 빌드 규칙을 지정할 수 있다. 타깃별 세부 구성은 다음과 같다.
- 빌드 환경(Build Config) : 각 타깃에 빌드 설정 값들의 묶음이다. 일반적으로 디버그용, 릴리스용 빌드 환경을 구분하고 각기 다른 빌드 설정을 저장한다. AdHoc배포처럼 배포 방식이 다를 경우, 새로운 빌드 환경을 추가하기도 한다.
- 빌드 단계(Build Phase) : 타깃의 제품을 빌드하기 위해 필요한 파일들을 단계별로 어떻게 처리할지 구성한 목록이다. 의존성이 있는 다른 타깃들, 컴파일 단계에서 사용할 소스들, 링크 단계에서 사용할 라이브러리나 프레임워크, 앱 번들에 복사할 리소스 파일들을 단계별로 지정하게 된다.
- 빌드 규칙(Build Rules) : 컴파일 단계와 리소스 복사 단계에서 파일 종류별로 어떤 어떻게 처리할지 규칙을 결정한다. 확장자 매칭 조건과 처리할 액션에 대한 지정을 할 수 있는데 기본적인 파일들에 대한 처리 규칙은 이미 자동적으로 생성된다.
- 빌드 설정(Build Setting) : 컴파일러나 링커에게 전달할 옵션들을 저장해놓은 목록이다. 빌드 설정은 유닉스 환경변수, Xcode 내장 변수, 프로젝트, 타깃 순으로 계층 구조를 이루어서 상위 계층의 값을 하위 계층에서 덮어쓰는 방식이다. 타깃에서 지정하지 않으면, 프로젝트에서 설정한 값아 타깃에 설정값으로 그대로 반영된다.
스킴(Scheme)과 목적지(Destination)
- 스킴은 프로젝트와 타깃 사이 개념으로 타깃별로 실행할 빌드, 실행, 프로파일, 분석, 아카이브 액션을 조합해서 지정할 수 있다. 기본적으로 타깃을 만들면 모든 액션을 다 수행할 수 있지만, 빌드와 테스트만 하는 스킴을 만들거나 분석과 성능 테스트만을 위한 스킴을 만들 수도 있다. 이렇게 설정한 스킴은 워크스페이스를 공유하는 개발팀이 서로 공유할 수 있어서 자신의 역할에 맞게 스킴을 선택하기도 한다. 특히 Xcode 서버에서 빌드를 하기 위해서는 반드시 빌드나 아카이스를 포함하는 스킴을 공유해야만 한다. 스킴과 목적지는 Xcode 화면 상단에 실행, 멈춤 버튼 우측에 있다.
- 목적지(Destination)은 스킴이 작동하는 환경을 지정하는 것이다. iOS 단말을 연결하면 Device 아래 표시가 되며, 시뮬레이터는 iOS Simulators 아래 표시가 된다. 만약 시뮬레이터가 없을 경우, Window 메뉴에서 Devices 항목을 선택하고 하단에 있는 +버튼을 눌러서 원하는 버전과 종류의 시뮬레이터를 추가할 수 있다. 참고로 배포를 위해서 아카이브를 할 때는 반드시 목적지가 시뮬레이터가 아닌 디바이스 중에 하나를 선택해야만 한다.
- 아카이브 액션은 배포를 위한 특별한 액션이다. 앱 스토어에 올리거나 사내에 인하우스 배포를 위해서는 반드시 아카이브를 해야 한다. 아카이브를 하면 배포를 위한 IPA 패키지를 생성하고, 이와 함께 크래시가 발생할 경우에 디버깅 정보를 위한 디버깅 심벌 DSym 파일을 함께 저장한다. 덕분에 아카이브한 버전별로 크래시 리포트를 확인할 수 있다. 아카이브와 크래시 목록은 Window 메뉴에서 Organizer 항목을 선택해서 확인할 수 있다.
- 아카이브 목록에서 앱 스토어에 올리기 위한 특정 버전을 선택하고 우측에 있는 Upload to App Store 버튼을 선택하면 배포용 인증서를 확인한 다음 앱 스토어에 올릴 수 있다. 여기서 앱을 올리기 전에는 반드시 iTunes Connect 사이트 MyApps 항목에서 해당 앱 설명과 올리려는 버전이 등록되어 있어야 한다.
✔︎ 환경 설정
- 일반 설정(General) : Xcode 개발 환경의 일반적인 공통 사항을 설정한다. 빌드 중에 이슈가 있을 때 멈추거나, 빌드하지 않더라도 실시간으로 이슈를 찾아주는 옵션 등이 있다.
- 계정 (Accounts) : 프로젝트에 연결된 소스 버전 관리 시스템의 저장소 계정이나, 애플 앱 스토어의 개발자 프로그램 계정까지 통합적으로 관리하는 메뉴를 제공한다.
- 동작 규칙 (Behaviors) : 특정 이벤트에 실행할 동작에 대한 규칙을 설정할 수 있다. 빌드 시작, 이슈 발생시, 실행 끝난 시점 등 이벤트 종류별로, 특정 소리나 말하기, 아이콘 튀기, 알림창 표시, 스냅샷 만들기 등 액션을 지정할 수 있다.
- 내비게이션 (Navigation) : 프로젝트 내비게이션이나 점프바에서 파일을 선택했을 때 어떻게 동작할지를 선택할 수 있다. 다양한 편집기를 표시하는 세부적인 옵션을 만들 수도 있다.
- 글꼴과 색상 (Fonts & Colors) : 편집 화면과 디버깅 콘솔 등에 사용하는 글꼴과 색상을 요소별로 선택할 수 있다.
- 편집기 (Text Editing) : 편집과 들여쓰기로 나눠진다. 편집 탭에서는 라인수 표시, 코드 접기 리본, 자동 완성 설정과 기본 텍스트 인코딩 값 등을 설정할 수 있다. 들여쓰기 탭에서는 탭과 공백 선택, 공백의 너비, 구문 분석 들여쓰기 조건 등을 변경할 수 있다.
- 키 바인딩 (Key Bindings) : 단축키를 원하는 형태로 바꾸기 위한 메뉴를 제공한다. 아쉽게도 emacs 스타일이나 Eclipse 스타일을 미리 제공하지는 않는다.
소스 관리 (Source Control) : SVN 이나 git 같은 소스 버전 관리 시스템과 관련해서 로컬, 서버의 최신 상태를 표시할지 여부를 선택할 수 있다. - 다운로드 (Downloads) : Xcode 설치 과정에 빠져있는 이전 버전 시뮬레이터나 버전별 개발자 문서 라이브러리 패키지를 다운로드 받을 수 있다.
- 위치 설정 (Locations) : 프로젝트 빌드 디렉터리, 스냅샷 저장 디렉터리와 아카이브 저장 디렉터리 등 빌드 결과에 대한 디렉터리 설정을 변경할 수 있고, 개발 환경의 상대 경로 설정을 위한 소스 트리 설정도 포함되어 있다.
(3) 문제 해결을 위한 노하우
✔︎ 문제 해결 방법
스냅샷(Snapshot)
- Xcode는 리팩터링 메뉴가 다른 개발환경에 비해서 상대적으로 다양하지 못하다. 그렇지만 리팩터링 메뉴를 선택하면 프로젝트 전체적으로 변화를 주기 때문에 경고를 보여주고 스냅샷을 남길 것을 권한다.
- 스냅샷은 현재 프로젝트 또는 워크스페이스의 상태를 사진을 찍듯 보관해두는 기능이다. 변화가 많은 작업을 하다가 과거의 특정 시섬으로 돌아가고 싶을 때, 백업해둔 스냅샷이 존재한다면 해당 스냅샷을 선택해서 복원하는 것이다.
- 파일 메뉴에서 Create Snapshot 항목을 선택하거나 키보드 단축키로 Control + Command + S를 누르고, 이름과 설명을 입력하면 원하는 스냅샷을 생성할 수 있다. 소스 버전 관리 시스템에 커밋하기 전에도 스냅얼마든지 복원할 수 있기 때문에 매우 유용하다.
- 복원하는 메뉴는 Window > Projects 항목을 선택하면 프로젝트별로 스냅샷 목록에서 특정 스냅샷을 선택해서 복원하면 된다.
브레이크 포인트 액션
브레이크포인트 문맥 메뉴에서 “Edit Breakpoint”를 선택하면 기본 브레이크포인트 편집화면이 표시된다. 여기서 Action 항목을 한 번 클릭하면 상세 액션 설정 화면이 표시되면서 애플스크립트, 디버거 명령, 로그 메시지, 셸 명령, 소리 중에서 선택할 수 있다. 이런 기능을 브레이크포인트 액션이라고 부른다.
브레이크 포인트 액션의 종류는 총 다섯 가지로 각 액션마다 입력화면도 다르다. 애플스크립트 액션을 선택하면 간단한 스크립트를 넣고 컴파일하고 테스트할 수 있는 화면을 제공하며, 디버그 콘솔에 로그를 남기도록 할 수도 있다. 원하는 코드에 브레이크포인트를 추가하고 로그를 남기도록 한다면, 브레이크 편집 메뉴를 선택해서 로그 메시지 액션 부분에 %B call … count = %H 라고 입력한다. 맨 마지막 항목인 옵션을 체크하면 특정 액션 수행한 다음에도 프로그램이 멈추지 않고 계속 실행해준다. Condition 항목은 어떤 변수의 값을 비교하는 것처럼 조건을 만족할 때만 동작하도록 하는 것이고, Ignore 항목은 처음 몇 번을 무시하도록 횟수를 지정해 줄 수 있다.
LLDB
LLDB는 애플이 추진하고 있는 오픈 소스 LLVM 프로젝트의 서브 프로젝트로 LLVM의 라이브러리들을 활용해서 만든 새로운 디버거로 GDB를 대체하기 위해 애플이 만든 것이다. 이제는 GDB 대신 LLDB가 시스템 기본 디버거다. C++ 언어로 만들어졌으며 GDB의 기능을 100% 호환하면서 더 빠르게 동작하도록 지금도 계속 새로운 기능을 추가하고 있다.
LLDB의 특징은 다음과 같다.
오픈소스 프로젝트
지원 플랫폼 : 맥 OS X i386 과 x86_64
지원 언어 : C/C++, Objetive-C/C++
확장성 : 파이썬 스크립트 지원
리모드 프로토콜 서버, 디버그서버 지원
멀티 쓰레딩 디거빙 지원 — inspection, stepping
메모리 변화 분석 Address Sanitizer 추가
✔︎ 확장 도구
정적 분석
- 오픈 소스 프로젝트인 Clang을 이용한 정적 분석은 iOS와 맥OS 기반 앱을 모두 지원하며 Cocoa API 와 메모리 관리, 로직 오류 등을 찾아내는 기능을 제공한다. 이것은 작성한 프로그램을 런타임에 실행해보지 않고 모든 소스 코드를 자동적으로 시스템이 검사해서, 테스트 케이스 없이도 미리 버그를 찾아서 고칠 수 있도록 도와준다.
- Product 메뉴에서 Analyze 항목을 선택하거나 Shift+Command+B를 누르면 프로젝트에 대해 정적 분석을 수행해서 결과를 시각적으로 표시해준다. 다만 정적 분석 자체가 완벽하지는 못해서 의도한 코드를 잘못된 코드로 인식하기도 한다.
- 정적 분석 방식으로 체크할 수 있는 항목은 다음과 같다.
Cocoa / CF API 호출 규격
메모리 관리 (Leak, GC 처리 등)
일반적인 오류 (포인터 처리, 초기값 참조 오류 등)
미참조 코드 (Dead stores)
인스트루먼트
- 앱의 안정성과 메모리 사용 최적화나 성능 개선 작업을 위해서 사용하는 프로파일 도구가 바로 인스트루먼트다. 인스트루먼트에는 메모리 분석용, 시스템 분석용, 파일 시스템과 입출력 분석, 그래픽 분석, 전원 사용량 분석, 코어 데이터 분석 등 다양한 템플릿을 제공한다.
- 인스트루먼트는 툴바와 세부 설정과 그래프, 분석 결과, 콜 스택 — 5가지 영역으로 구분된다. 툴바는 Xcode의 모습과 유사한 형태로 분석 중인 타깃과 시간 정보, 각 화면을 보거나 가릴 수 있는 기능을 제공한다. 인스트루먼트 세부 설정 (Instruments)은 위 부분에서 선택한 인스트루먼트 항목별로 상세한 설정 변경을 하는 곳으로 분석 결과를 여러 형태로 간추려 표시하는 기능을 제공한다. 분석 결과 (Detail)는 기록 시간 동안 변화를 기록하는 그래프 영역과 함께 해당 인스트루먼트의 기능에 따라 각기 다르게 정리된 데이터를 표시해준다.
- 예를 들어 메모리 누수를 위한 Leaks의 템플릿의 경우 할당되고 해제되지 않은 메모리에 대한 정보를 표시한다. Allocations 항목을 선택하면 기록 시간 동안에 변화한 메모리 할당 기록을 모두 표시해줄 것이다. 콜 스택 영역 (Extended Detail)은 분석 결과를 선택한 경우에 해당 문제를 일으킨 함수에 대한 콜 스택을 표시해주고, Xcode 코드와 연결해서 보여주기도 한다.
플러그인 확장
- 코코아팟 (CocoaPods) : 코코아팟은 루비로 만들어진 오픈 소스 프로젝트로 Xcode에서 사용하는 외부 라이브러리 의존성 관리 도구다. 프로젝트에서 사용하는 라이브러리 명칭과 버전을 pod 목록 파일로 작성하고 pod 명령을 실행하면 프로젝트와 라이브러리 의존성을 분석해서, 필요한 라이브러리는 새로 다운로드 받고 전체를 하나의 워크스페이스를 생성해준다.
- Xcode 플러그인 : 애플이 공식적으로 플러그인을 배포하지는 않지만, 이미 많은 개발자들이 개발 환경에 필요한 기능을 플러그인으로 만들어서 공개하고 있다. 그 중에서도 알카트라즈(http://alcatraz.io/) 프로젝트는 Xcode를 위한 오픈소스 확장 패키지 관리 도구다. 플러그인이나 컬러 스킴, 프로젝트 템플릿 등을 확장할 수 있는 기능을 제공한다.
- 알카트라즈 자체도 비공식적인 확장 도구라서, Xcode가 알카트라즈 번들을 로딩할 때마다 경고창이 나타나기는 하지만 개발 과정에서는 편리한 기능들이 많다. 그 중에서도 검증된 유용한 플러그인들은 다음과 같다. (Xcode8에서는 불가능한 플러그인도 있다 ㅜㅜ)
CocoaPods Manager : 코코아팟 관련 명령들을 Xcode 메뉴에 추가해서 pod 목록을 관리하기 쉽도록 확장해준다.
GitDiff : 소스 관리 도구나 명령창에서 gifdiff를 하지 않다라도 이전 버전과 비교해서 바뀌거나 추가한 부분을 줄번호 옆에 표시해는 기능을 제공한다.
KSImageNamed : 프로젝트의 이미지 리소스 파일명을 찾아서 자동 완성해주는 기능을 제공한다.
FuzzyAutocomplete : 유난히 긴 Objective-C 스타일 메서드 명칭 때문에 자동완성 기능으로도 찾기 힘든 경우가 많다. 이 플러그인을 설치하면 메서드 명칭에서 부분 검색을 지원하도록 확장해 준다.
ColorSence : UIColor를 코드로 생성할 때 컬러값을 편집기 화면에 미리보기 형태로 보여준다.
✔︎ 개발 과정의 노하우
개발 언어와 프레임워크 트랜드
- 애플은 2014년 WWDC 개발자 컨퍼런스에서 스위프트(Swift)라는 새로운 언어를 발표했다. 오브젝티브-C가 만들어진지 30년이나 지난 오래된 언어라 가지는 한계를 극복하기 위한 선택이었다. 2015년 6월에는 Swfit 2.0버전을 공개하고, 같은 12월에는 오픈소스 프로젝트(http://swift.org)로 완전히 공개했다.
- iOS 앱을 개발하기 위해서 필요한 3가지 요소는 Xcode에서 제공하는 개발 환경과 코코아 터치를 시작으로 애플의 여러 프레임워크들, 그리고 프로그래밍 언어로 오브젝티브-C와 스위프트라고 할 수 있다. 기존까지는 무조건 오브젝티브-C로만 개발해야 했다면, 이제부터는 스위프트도 앱을 개발할 수 있다. 어떤 언어를 선택한다고 해서 제약사항이 있다거나 어떤 불이익을 받지는 않는다.
- 오브젝티브-C를 사용해서 예전부터 앱을 개발자나 개발 회사는 여전히 오브젝티브-C로 개발을 하고 있고, 새롭게 프로젝트를 시작하거나 스위프트를 배워보고 싶은 개발자들은 스위프트로 개발을 하고 있다. 스위프트 1.x버전까지는 스위프트로 작성한 프레임워크보다는 기존에 오브젝티브-C로 작성한 코드를 브릿지해서 사용해야 하는 프레임워크가 더 많았다. 하지만 스위프트 2.0부터는 iOS 앱을 개발하는데 필요한 주요한 프레임워크 중에 30여가지 이상을 스위프트로 재작성하고 빌드해서 제공하고 있다.
- 스위프트는 만들어진지 얼마되지 않은 신생 언어라서 모던한 최신 언어들의 특성을 상당히 자연스럽게 흡수하고 있다. 더불어 오브젝티브-C와 상호 호환성을 갖고 있어서 코코아 프레임워크의 특성도 일부 갖고 있다. 객체지향 프로그래밍 방식 뿐만 아니라 메타 프로그래밍 패러다임이나 함수형 패러다임 특성도 함께 갖고 있는 게 특징이다.
- 다음은 오브젝티브-C와 달리 스위프트가 갖고 있는 특징이다.
네임스페이스(Namespace) : C 기반으로 만들어진 오브젝티브-C는 네임스페이스를 지원하지 않아 객체명이나 메서드명, 함수명이 겹치는 경우가 많다. 스위프트는 네임스페이스를 지원한다.
제네릭(Generics)과 타입 추정 : 객체와 클래스로 추상화 작업을 하는 오브젝티브-C와 달리 스위프트는 함수형 언어의 특징을 많이 지원한다. 그 중에서도 타입 추정과 제네릭은 함수와 데이터 구조를 추상화하는 데 도움을 준다. 스위프트 2.0과 함께 호환성을 더 높이기 위해서 오브젝티브-C 언어 기반 파운데이션 콜랙션 객체들은 제네릭을 지원하기 시작했다.
고차함수 지원 : map, filter, recude 같은 함수를 인자로 받는 고차 함수를 지원해서 코드를 좀 더 간결하게 만들어준다. 오브젝티브-C에서는 블록을 활용하는 API들이 많아지고 있어서 비슷한 표현이 가능하다.
프로토콜 기반 확장 : 스위프트의 프로토콜은 오브젝티브-C의 프로토콜 보다 더 확장된 개념으로 클래스 뿐만 아니라 여러 종류의 타입을 확장하는 용도로 활용한다 - 애플의 프레임워크도 스위프트와 오프젝티브-C를 모두 지원하는 방향으로 발전하고 있다. 기존에 오브젝티브-C로 작성한 라이브러리도 일부 스위프트 네이티브로 재작성하고 LLVM 컴파일러 기술을 활용해서 스위프트 전용 프레임워크로 포팅하고 있다. 이런 라이브러리들 중에 일부는 iOS 뿐만 아니라 리눅스에서도 스위프트로 개발할 수 있도록 지원하고 있다.
- 애플은 2015년부터 iOS를 기반으로 한 워치OS와 tvOS를 내놓으면서 플랫폼을 확장해가는 추세다. 이제 iOS 앱은 애플워치에서 어떤 정보를 알려주고, 어떻게 사용자 경험을 이어주고, 애플TV나 홈킷을 연동하는 가전 제품까지 점차 사용자 경험을 넓혀가도록 유도하고 있다. iOS 앱 개발을 시작하면서 애플의 새로운 플랫폼을 어떻게 활용할 것인지 전략적인 고민도 필요하다.
유용한 오픈소스들
- AFNetworking 네트워크 확장 라이브러리https://github.com/AFNetworking/AFNetworking
- RestKit RESTful 웹 리소스 라이브러리 _ https://github.com/RestKit/RestKit
- GPUImage GPU-기반 이미지/비디오 프로세싱https://github.com/BradLarson/GPUImage
- ViewDeck 패스/페이스북 스타일 좌측 슬라이딩 데크 https://github.com/Inferis/ViewDeck
- FastImageCache 이미지 캐시 관리https://github.com/path/FastImageCache
- iCarousel 3D 캐로셀 애니메이션 https://github.com/nicklockwood/iCarousel
- pop 페이스북 애니메이션 확장 라이브러리
- https://github.com/facebook/pop
- CocoaLumberjack 간단하고 빠른 로그 라이브러리https://github.com/CocoaLumberjack/CocoaLumberjack
- Reader PDF 리더 코어 엔진 https://github.com/vfr/Reader
- PonyDebugger 크롬 개발자 도구를 쓸 수 있는 리모트 로그/디버그 도구 https://github.com/square/PonyDebugger
- SDWebImage 이미지 다운로더 및 캐시 라이브러리https://github.com/rs/SDWebImage
- Toast 안드로이드 스타일 Toast 라이브러리https://github.com/scalessec/Toast
- SVProgressHUD 로딩창 및 진행 팝업 라이브러리https://github.com/samvermette/SVProgressHUD
- FMDB Core Data 안쓰고 sqlite Wrapper 라이브러리https://github.com/ccgus/fmdb
Xcode 서버 활용
- Xcode 서버는 OS X Server 앱을 설치해야만 사용할 수 있는 확장 서비스로, Xcode를 활용해서 CI(Countinuous Integration) 서버 기능을 제공해준다. 허드슨(Hudson)이나 젠킨스(Jenkins) 같은 다른 CI 도구로 빌드 환경을 만들 수도 있지만 애플이 제공하는 확장 기능을 쓰면 단말 테스트까지 자동화할 수 있는 부분이 더 많다.
- OS X Server 앱을 맥 앱 스토어에서 $21.99 가격으로 직접 구매하거나 혹은 유료 개발자 프로그램에 가입했다면 무료로 받을 수 있는 리딤코드를 이용해서 받으면 된다. 개발자가 개인용 맥북에 설치하기 보다는 공용 아이맥이나 맥미니 같은 데스크톱 맥을 이용해서 설정하는 것을 권장한다. 물론 해당 맥에는 최신 Xcode도 함께 설치해줘야 한다.
- OS X Server를 받고 실행해서, Xcode 서비스를 활성화(ON) 시킨다. 주기적으로 봇을 동작할 소스의 저장소를 등록하고, 빌드할 때 사용할 개발자 계정 프로파일을 설정한다. 추가적으로 해당 맥에 연결해서 테스트에 사용할 디바이스도 등록할 수 있다. iOS 버전별, 단말기별로 빌드 이후에 테스트 자동화에 사용할 수 있다.
- Xcode 서버 서비스에서 자동 작업을 할 봇(bot)은 개발자 맥의 Xcode에서 원격으로 설정하면 된다. Product 메뉴 맨 아래 Create Bot 메뉴를 선택하고 공유된 스킴, 봇 이름, 서버 등을 입력한다. 봇의 작업 스케줄을 설정할 때는 주기적으로 원하는 시간, 요일마다 빌드할 수도 있고, 커밋이 있을 때마다 빌드를 할 수도 있다. 그리고 빌드 이후에 테스트 스위트에 작성된 테스트 케이스들을 어떤 디바이스에서 진행할 것인지 설정한다. 마지막으로 성공이나 실패 시점에 이메일로 통보받을 주소를 입력하면 된다.
- 최신 버전부터는 CI 서버 기능을 REST API로 제공하고 있어서 다른 CI 서버나 빌드 서버에서 통합할 수 있다. 그리고 인하우스 배포를 위한 홈페이지를 자동적으로 생성해주기 때문에 엔터프라이즈 개발자 프로그램에 가입한 경우라면 Xcode 서비스에서 만들어주는 배포 링크를 활용해서, 홈페이지 주소만 알려주면 앱을 손쉽게 배포할 수도 있다. 다만 iOS 9부터는 배포 서버에 대한 악의적인 접근을 막기 위해서 IP 주소로 앱 배포가 안되고 사내 DNS 설정을 통해서 도메인 네임으로 접근을 해야만 한다.
✔︎ 참고문헌
- 국내문헌
인사이트. 2010. 매력적인 맥/iOS 개발 환경 : Xcode. 김정. - 국외문헌 및 사이트
애플 개발자 사이트 개발자 라이브러리 : https://developer.apple.com/library/ios/navigation/
개발자 리소스 동영상 : https://developer.apple.com/videos/
개발자 프로그램 가입 : https://developer.apple.com/programs/
애플 아이튠즈 스토어 심사 가이드 : https://developer.apple.com/app-store/review/guidelines/kr/
아이튠즈 가이드
https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SettingUpUserAccounts.html - 기타
맥/iOS 개발자 커뮤니티 : http://osxdev.org
코드스쿼드 마스터 김정입니다. iOS 및 모바일 분야를 담당하고 있습니다.
http://codesquad.kr/
https://www.facebook.com/codesquad.kr/