8 13 2008
Hello, iPhone 2.0 어플리케이션 개발하기
iPhone 개발자 프로그램에 가입한 후 Free iPhone SDK (약 1.25GB) 를 다운로드 받았다.
Object-C도 잘 모르지만 예제로 제공되는 Hello, World!를 iPhone Simulator에서 실행해보고 소스를 보니 대충은 알 것도 같은 느낌이 들어 Hello World!를 내가 Hello, iPhone 2.0으로 만들어 보기로 했다.
모든 프로그래밍 언어는 Hello, World!를 만드는 것부터 시작하는 것 아닌가!
프로젝트 생성
Free iPhone SDK에는 Xcode 3.1이 포함되어 있고 Xcode는 /Developer/Applications 디렉토리에 있다.
Xcode를 실행하고 ‘File’ 메뉴의 ‘New Project’를 선택하면 템플릿을 선택하도록 대화 창이 뜬다.
대화 창에서 ‘View-Based Application’을 선택하고 ‘Choose’ 버튼을 누른다.

프로젝트 명을 ‘TakeOne’이라고 지정하고 ‘Save’ 버튼을 누르면 Xcode는 템플릿을 사용하여 기본적인 파일을 자동으로 만든다.

12개의 파일이 자동으로 생성된 것을 볼 수 있는데 일단 ‘Build and Go’를 눌러 iPhone Simulator에서 실행해 본다.

아무 작업도 하지 않았으니 하얀 화면만 출력된다. ‘Home’ 버튼을 눌러보면 ‘TakeOne’ 아이콘도 지정하지 않았으므로 그냥 빈 아이콘이다.
정상적으로 프로젝트 생성은 되었다. 이제 템플릿으로 생성된 파일을 수정하여 개발하면 된다.
인터페이스 생성
먼저 배경으로는 Hello, World! 예제의 배경화면을 그대로 사용한다. 이 파일을 프로젝트에 추가하기 위해서 다음과 같이 한다.
(1) ‘Groups & Files’의 ‘Resources’를 선택하고 마우스 오른쪽 버튼을 누른다.
(2) 메뉴에서 ‘Add’를 선택하고 ‘Existing Files’를 선택한다.

(3) 파일 선택 대화창에서 Hello, World 예제의 Background.png 파일을 선택한다.
(4) 다음과 같은 대화상자가 나타나는데 Copy items into destination group’s folder 를 체크되어 있는 지 확인한다.

그리고 배경은 그대로 사용하되 아이콘은 구별을 위해 간단하게 제작을 하였다.
이제 Resources에 있는 TakeOneViewController.xib 파일을 더블 클릭하면 Interface Builder가 뜬다.

View 창이 역시 빈 화면이다. Library 창의 Media를 클릭한 후 Background.png 파일을 선택하고 View 창으로 드래그하여 드롭한다. 제작한 Icon.png 파일도 View 창에 놓아 배경만으로도 예제의 Hello, World와 구별되도록 했다.

다시 Objects를 클릭한 후 Label, Text Field 를 찾아 드래그하여 View 창에 드롭하고 위치와 크기를 조정한다.

완성한 디자인은 다음과 같다. 위에서 언급한 것과 같이 TAKE ONE 이라고 만든 아이콘으로 인해 쉽게 Hello, World 예제외 구별된다.
Text Field를 선택하고 Interface Builder의 ‘Tools’ 메뉴의 ‘Attribute Inspector’를 선택하면 속성 창이 뜬다.

Text Field에 기본으로 출력될 메시지를 Placeholder에 입력한다. 나는 Hello, iPhone 2.0을 입력하였다.
그리고 Label을 선택하여 Text 값을 지웠다.
프로그래밍
이제 코드를 입력할 차례이다. 아래 수정된 코드는 Hello, World의 예제를 활용한 것이다.
- TakeOneViewController.h 수정. 템플릿으로 생성된 소스는 다음과 같다.
#import <UIKit/UIKit.h> @interface TakeOneViewController : UIViewController { } @end이 소스를 다음과 같이 변경한다.
#import <UIKit/UIKit.h> @interface TakeOneViewController : UIViewController { // 텍스트 필드 IBOutlet UITextField *msgText; // 레이블 IBOutlet UILabel *msgLabel; // 문자열 NSString *tmpMsg; } @property (nonatomic, retain) UITextField *msgText; @property (nonatomic, retain) UILabel *msgLabel; @property (nonatomic, copy) NSString *tmpMsg; // 메소드 추가 - (void)updateString; @end - TakeOneViewController.m 수정. 템플릿으로 생성된 소스는 다음과 같다.
#import "TakeOneViewController.h" @implementation TakeOneViewController /* Implement loadView if you want to create a view hierarchy programmatically - (void)loadView { } */ /* Implement viewDidLoad if you need to do additional setup after loading the view. - (void)viewDidLoad { [super viewDidLoad]; } */ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview // Release anything that's not essential, such as cached data } - (void)dealloc { [super dealloc]; } @end수정한 소스는 다음과 같다.
#import "TakeOneViewController.h" @implementation TakeOneViewController @synthesize msgText; @synthesize msgLabel; @synthesize tmpMsg; /* Implement loadView if you want to create a view hierarchy programmatically - (void)loadView { } */ /* Implement viewDidLoad if you need to do additional setup after loading the view. - (void)viewDidLoad { [super viewDidLoad]; } */ - (void)viewDidLoad { // 사용자가 입력하기 시작하면 텍스트 필드에 지우기 버튼이 보인다. msgText.clearButtonMode = UITextFieldViewModeWhileEditing; // 뷰가 처음 로드되었을 때 레이블에 텍스트 필드에 설정된 기본 값이 출력된다. msgLabel.text = msgText.placeholder; } - (void)updateString { // 텍스트 필드의 텍스트를 'tmpMsg' 인스턴스 변수에 저장한다. self.tmpMsg = msgText.text; // 'tmpMsg' 인스턴스 변수의 값을 레이블의 텍스트로 설정한다. msgLabel.text = self.tmpMsg; } - (BOOL)textFieldShouldReturn:(UITextField *)theTextField { // 사용자가 리턴을 누르면 텍스트 필드로 부터 포커스를 제거하여 키보드가 사라진다. if (theTextField == msgText) { [msgText resignFirstResponder]; // 인사말을 변경하는 메소드 호출 [self updateString]; } return YES; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 텍스트 필드의 밖을 터치하면 키보드가 사라진다. [msgText resignFirstResponder]; msgText.text = self.tmpMsg; // 이전 값으로 텍스트 필드를 되돌린다. [super touchesBegan:touches withEvent:event]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview // Release anything that's not essential, such as cached data } - (void)dealloc { // 메모리 관리 규칙을 따르기 위해 인스턴스 변수를 해제한다. // 'msgText'와 'msgLabel'은 nib 파일의 객체이고 이들은 nib가 로드되었을 때 생성된다. [msgText release]; [msgLabel release]; [super dealloc]; } @end
소스와 인터페이스 연결
- View 연결
먼저 View를 File’s Owner 즉 위에서 만든 TakeOneViewController 로 연결한다.
View를 선택하고 마우스 오른쪽 버튼을 누른 후 나오는 창에서 New Referencing Outlet의 오른쪽의 동그라미에 마우스를 가져가면 + 로 변경된다.그러면 마우스를 클릭하고 그래도 File’s Owner로 드래그하고 마우스를 놓으면 소스에 view 라고 잡혀있는 변수 명이 나타난다.

view를 선택하면 아래와 같이 File’s Owner가 추가된 것을 확인할 수 있다.

- 이제 Label을 선택하고 위와 같은 방법으로 File’s Owner로 드래그하여 msgLabel로 연결한다.
- Round Style Text Field를 선택하고 Outlets의 delegate를 File’s Owner로 연결한다.

그리고 스크롤 하여 Referencing Outlets은 File’s Owner로 드래그하여 msgText로 연결한다.
테스트
작업이 완료되었으므로 ‘Build and Go’를 눌러서 테스트한다.


정상적으로 동작하는 어플리케이션이 완성되었다.
Xcode에 아직 익숙치 않지만 Xcode는 꽤 괜찮은 개발 툴로 판단된다. 쉽게 개발할 수 있는 도구가 잘 갖추어져 있다.
참고