Tag Archives: iOS

XCode 6 Framework 만들기

xcode6_framework_01

XCode 6버전에 들어서면서 손쉽게 만들기 어려웠던 Cocoa Touch Framework 프로젝트를 만들 수 있게 되었습니다. 이 프로젝트의 경우 Target이 Framework가 되며 실제로 빌드를 할 경우 XCode DerivedData 디렉토리안에 빌드된 Framework가 생성됩니다. 이렇게 빌드된 Framework를 당신이 원하는 프로젝트에 드래그&드롭을 하게 되면 간단하게 Framework가 추가되며 안에 있는 기능들을 호출할 수 있게 됩니다.

Framework 만들기

지금부터 간단한 Framework를 제작하고 예제앱에 추가하여 사용하는 방법을 구현해 보도록 하겠습니다. 지금부터 진행할 예제는 하나의 Workspace안에 두개의 프로젝트(Framework, App)로 구현할 것인데 Workspace 없이 별개의 단일 프로젝트를 각각 구현하셔도 괜찮습니다.

xcode6_framework_02

File > New > Workspace를 선택하여 개발을 할 워크스페이스를 하나 만들어줍니다. 저는 HelloFrameworkExample로 만들어보겠습니다.

xcode6_framework_03

그럼 완전 아무것도 없는 빈 IDE가 등장합니다. 다시 File > New > Project 메뉴를 선택하여 프로젝트를 추가해줍니다.

xcode6_framework_04 xcode6_framework_05

스크린샷과 같이 Cocoa Touch Framework를 선택하고 Next를 눌러 진행합니다. 다음은 프로젝트의 기본 설정을 하게 되는데 적당히 본인의 환경에 맞춰주시면 됩니다. 언어의 경우 Swift, Objective-C 둘중에 하나를 선택할 수 있는데 저는 일단 Objective-C로 진행을 하도록 하겠습니다.xcode6_framework_06

마지막에 소스가 저장될 디렉토리를 설정하는데 하단에 Add to에 현재 추가할 Workspace를 선택해주어야 작업할 워크스페이스에 추가됩니다. Git Source Control은 예제 프로젝트이므로 사용하지 않을 생각입니다.xcode6_framework_07

생성된 Cocoa Touch Framework의 디렉토리 구조도는 위와 같습니다. Framework Import시에 가장 기본으로 불려질 HelloFramework.h와 프로젝트 설정이 담겨있는 Info.plist와 테스트 코드들이 담겨있습니다.

소스파일이 아닌 프로젝트 자체를 선택했을때 오른쪽에 뜨는 프로젝트 설정에 주목할 부분은 Deployment Target 설정입니다. Framework가 갖는 특성이 다양한 환경에서 실행되어야 하는 라이브러리라고 볼 때 더 많은 환경에서 구동되도록 구현하는것은 당연해 보입니다. Deployment Target의 경우 실행 가능한 가장 낮은 버전을 설정하게 되는데요. 현재 시점에서 선택할 수 있는 합리적인 버전은 5.1.1이지 않나 생각합니다.

2015년 2월부터 Apple에서는 앱스토어에 등록하는 모든 앱이 64비트를 지원할것을 강제화 했습니다. Framework가 32비트와 64비트를 동시에 지원할 수 있는 가장낮은 Deployment Target은 5.1.1입니다. 실제로 더 낮은 버전을 설정하면 다음과 같은 경고 메시지를 볼 수 있습니다.

xcode6_framework_08

위의 Deployment Target 설정과 연계하여 Build Setting에 대해서도 확인해 봅시다.

xcode6_framework_09

여기서 주목해야 하는 설정은 Architectures와 Valid Architectures 설정입니다. 보면 32비트 아키텍쳐인 armv7/armv7s와 64비트 아키텍쳐인 arm64를 모두 지원하는것을 알 수 있습니다. 그 다음으로 확인해야 하는 부분은 Build Active Architecture Only 설정입니다. 기본 설정은 Debug에 한해 Yes로 되어있습니다만 이렇게 되어있을 경우 Simulator 환경에서는 i386으로만 빌드가 됩니다. 하지만 당신의 환경이 x86_64 아키텍쳐 환경을 필요로 할 수 있으므로 No로 바꾸어 가능한 모든 환경에서 동작하도록 빌드를 합시다.

xcode6_framework_10

이제 간단한 예제 API를 만들어봅시다. File > New > File 메뉴를 선택하거나 마우스 우클릭 후 Add File을 선택하여 Cocoa Touch Class를 추가합니다.

xcode6_framework_11

Person이라는 클래스를 추가해보겠습니다. IDE에 새로운 두개의 파일(.h/.m)이 생성된것을 확인할 수 있습니다. 다음과 같이 간단한 데모 코딩을 해보겠습니다.

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (instancetype)initWithName:(NSString *)name age:(int)age;
- (void)info;

@end
#import "Person.h"

@interface Person ()

@property(strong, nonatomic) NSString *name;
@property(nonatomic) int age;

@end

@implementation Person

- (instancetype)initWithName:(NSString *)name age:(int)age
{
    if(self = [super init]) {
        self.name = name;
        self.age = age;
    }
    return self;
}

- (void)info
{
    NSLog(@"The person's name is %@ and his age is %d", self.name, self.age);
}

@end

위의 코드에 대한 내용은 굳이 설명하지 않아도 괜찮을 것이라 생각하고 패스하겠습니다^^ 하지만 초기화후에 info를 호출하여 NSLog로 값들을 출력한다는것만 기억해두도록 합시다.

xcode6_framework_12이렇게 추가된 클래스가 Framework 외부의 프로젝트에서 접근가능해야 할 경우 위와 같은 설정이 필요합니다. 클래스의 헤더파일을 선택하면 (위의 예시는 Person.h) 오른편에 Target Membership란이 보이는데 Framework와 Test가 보입니다. Framework 오른편에 Visibility 설정을 할 수 있습니다. Public으로 바꿔주어야 이 Framework를 사용하는 다른 프로젝트들이 자유롭게 이 클래스를 사용 할 수 있습니다. 기본적으로 Project로 되어있는데 Project의 경우 해당 프로젝트 이내(여기서는 Framework 자기 자신)에서만 접근이 가능하며 Private는 프로덕트에는 포함이 되지만 사용되기 원하지 않는 개발단계의 클래스들을 지정할 때 사용합니다.

마지막으로 HelloFramework.h 헤더파일에 추가한 클래스를 Import 선언해 줍니다. 여기에 선언하는 모든 클래스는 이 Framework를 Import하였다면 자유롭게 사용할 수 있게 됩니다. Framework 내부에서만 사용될 클래스는 여기에 선언하지 않도록 합니다.

#import <UIKit/UIKit.h>

//! Project version number for HelloFramework.
FOUNDATION_EXPORT double HelloFrameworkVersionNumber;

//! Project version string for HelloFramework.
FOUNDATION_EXPORT const unsigned char HelloFrameworkVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <HelloFramework/PublicHeader.h>

// 외부에서 자유롭게 접근할 클래스의 헤더들을 다음처럼 선언해 줍니다.
#import <HelloFramework/Person.h>

이것으로 예제 Framework를 만들어 보았습니다. 이제 한번 빌드를 해보도록 하겠습니다. Product > Build 메뉴를 선택합니다. 특별히 잘못한 것이 없다면 오류 없이 빌드가 성공할 것입니다.

xcode6_framework_13

처음에 보면 Products 이하의 파일들은 빨간색으로 표시되고 있습니다. 파일이 없는(Missing) 상태임을 뜻합니다. 빌드를 하면 생길것이라 생각되어 빌드를 해도 변화가 없는것을 확인할 수 있습니다. Products 이하의 파일들은 실제 환경인 Device 환경에서 빌드된 파일들을 표시합니다. 처음에는 기본적으로 Simulator가 선택되어있어 Simulator 빌드가 수행되므로 여기에 표기가 되지 않습니다.

상단의 Build Scheme 설정 옆에 iOS Device / Simulator를 선택할 수 있는 부분이 있습니다. 여기서 iOS Device를 선택합니다. 이후에 다시 Build를 수행하면 Products 이하의 바이너리들이 검정색으로 바뀝니다. 빌드가 성공했군요.xcode6_framework_14

빌드된 .framework파일을 선택하고 오른쪽의 Inspector를 보면 Full Path가 표시됩니다. 마지막에 화살표 아이콘이 있는데 저 아이콘을 누르면 해당 디렉토리로 바로 이동하여 Framework 파일의 위치를 보여줍니다. 이창을 띄워둔 상태로 예제앱을 만들어보도록 하겠습니다.

예제앱 만들기

이번에는 만들어둔 Framework를 활용한 간단한 예제앱을 만들어보도록 하겠습니다. File > New > Project를 선택하여 새로운 프로젝트를 생성합니다. 프로젝트 이름은 HelloApp으로 하겠습니다.

xcode6_framework_15 xcode6_framework_16

간단히 Framework가 동작하는것을 확인하기만 할것이기에 무엇을 선택해도 상관없지만 Single View Application으로 만들어보겠습니다.

xcode6_framework_17

마찬가지로 Add to 설정에서 기존에 만들어둔 Workspace를 재활용 할 수 있도록 설정해 줍니다. 이제 HelloApp도 XCode에 추가되어 작업할 수 있게 되었습니다.

xcode6_framework_18

아까 열어두었던 창의 HelloFramework.framework 파일을 드래그하여 추가해줍니다. 여기서 복사를 하여도 되고 Framework가 계속 변화가 이루어지는 상황이라면 Reference만 추가해놓고 Framework의 업데이트가 바로 적용되도록 할 수도 있습니다. 이제 Framework를 Import하여 사용해 보도록 하겠습니다. 첫번째 뷰인 ViewController.m에 추가해보겠습니다.

#import "ViewController.h"
#import <HelloFramework/HelloFramework.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // Framework의 Person 클래스를 사용
    Person *person = [[Person alloc] initWithName:@"Hello" age:19];
    [person info];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Person클래스의 info메소드를 호출하게 되면 NSLog를 통해 이름과 나이를 출력하게 만들어져있는것을 이전에 확인하였습니다. 정말로 제대로 호출이 되는지 실행을 해보겠습니다.

xcode6_framework_19

실행전에 Build Scheme과 적당한 실행 디바이스가 선택되어있는지 확인하고 빌드하시기 바랍니다. 저는 일단 심뮬레이터에서 구동해보겠습니다.

xcode6_framework_20

원하는 값이 정상적으로 출력이 되었군요^^

Xcode 6 Playground 사용하기

swift-screenshot

Xcode 6에서 새로 생긴 기능으로 Playground 라는것이 있습니다. Playground 에서 Swift 코드를 인터렉티브한 환경에서 테스트할 수 있습니다.  코드들을 컴파일 하거나 컴파일이 완료된 프로젝트를 실행하지 않고 Playground에서 당신의 실험적인 코드들의 결과를 빠르게 확인할 수 있습니다.

Playground 둘러보기

xcode_playground_01

Xcode를 실행했을 때 “Get started with a playground”를 선택하여 곧바로 Playground 프로젝트를 실행할 수 있습니다. 또는 File > New > Playground 를 선택하여 시작할 수 있습니다.

xcode_playground_03

.playground라는 확장자를 가진 파일이 생성되며 위와 같이 결과가 바로 출력되는 사이드바를 가진 창을 확인할 수 있습니다. Playground에서의 Xcode는 당신이 코드의 한 문장이 끝나거나 타이핑을 잠시 멈췄을 때 코드의 결과를 소스 에디터 오른편에 위치한 사이드바에 출력합니다.

xcode_playground_04

이제 몇가지 테스트용 코드를 작성하여 보았습니다. 오른쪽 사이드바를 보면 작성한 함수가 호출될때 내부적으로 어떻게 값이 변하는지 함수의 결과값이 무엇인지 변수의 값이 무엇인지 순환문이 몇번 반복되는지 여부를 확인할 수 있습니다.

xcode_playground_05

의도적이지만 잘못된 코드를 한번 작성해보았습니다. 이미 정의된 j를 재정의 해보려고 하였더니 곧바로 에러가 출력되는것을 확인할 수 있습니다. Xcode는 친절하게도 당신이 작성중인 코드의 잘못된 부분을 빨간색 느낌표 심볼을 사용하여 즉시 알려줍니다. 저 심볼을 클릭하게 되면 무엇을 실수하였는지 상세한 설명을 볼 수 있습니다. 실수한 부분을 알맞게 수정하거나 삭제하면 Xcode는 코드의 정상적인 실행 결과를 오른쪽 사이드바에 다시 표시해 줍니다.

xcode_playground_06

코드의 중간에 변수의 값을 확인하고 싶다면 별도의 라인에 변수명을 적기만 하면 됩니다. 위의 예시를 보면 width와 height 변수를 각각 별도의 라인에 적어줌으로써 사이드바에 결과값을 확인할 수 있습니다.

xcode_playground_07

사이드바의 순환문의 결과부분에 마우스 커서를 올려보면 위와 같은 동그라미 아이콘이 보여집니다. Value History Button이라고 하는데요, 이것을 눌러 오른쪽과 같은 값의 변화를 그래프로 확인할 수 있습니다. 심지어 소요된 시간을 확인할 수 있어 시간이 많이 소요되는 순환문의 경우 이 그래프를 확인하며 최적화 작업을 할 수 있습니다.

xcode_playground_08

이 그래프의 X축은 시간의 변화를 보여주며 Y축은 값의 변화를 보여줍니다. 위의 스크린샷과 같이 특정 지점을 마우스로 클릭하면 그 지점의 값을 확인할 수 있습니다.

xcode_playground_09

오른쪽 하단에 보면 Timeline 이라고 불리는 막대바가 있습니다. 이 바를 움직여보시면 하나의 순환문이 아닌 전체 코드들의 실행 순서를 차례대로 돌려볼 수 있습니다. 실제로 오래걸리는 순환문을 만들어 보면 그것이 실행되면서 그래프를 그리는 모습을 눈으로 관찰하실 수 있습니다.

Timeline의 막대바 옆에는 얼마나 오래동안 이 그래프가 만들어지는 과정을 보여줄것인가 제한을 설정할 수 있습니다. 레퍼런스를 읽어봤을때는 동작이 제한 시간에 걸리면 멈추는것으로 나와있는데요 테스트해본 결과 멈추지 않고 모두 실행되어 버리는것을 확인하였습니다. 좀더 확인을 해봐야 할것 같네요.

UIKit을 활용한 테스트 코드 작성하기

기본 환경에서 Playground를 사용중이라면 UILabel이라던가 UIView와 같은 UIKit에 포함된 컨트롤러를 이용한 테스트 코드를 사용할 수 없는것을 확인할 수 있었습니다. UIKit을 Import하면 당연히 될것이라 생각했는데 안되더군요. 다음과 같은 설정을 해주시면 간단히 가능하게 됩니다.

xcode_playground_10

View > Utilities > Show File Inspector 에 진입해 보면 Playground Settings가 있습니다. 여기에 Platform 설정을 iOS로 바꿔주시면 됩니다. 이제부턴 UIKit을 사용할 수 있게 되었습니다.

xcode_playground_11

이거 정말 멋지다고 생각하는데요. 현재 만들어지는 있는 각각의 컨트롤러에 대해 사이드뷰에서 눈 모양의 아이콘을 클릭하면 현재 모습을 확인할 수 있습니다. 특정 UI를 만들겠다면 정말 손쉽게 구현해보고 테스트 해볼 수 있을것 같습니다.

참고자료 : Exploring and Evaluating Swift Code in a Playground