최초 작성일 : 2010/05/01 17:37 


일단 처음으로 아이폰에서 동작하는 앱을 하나 만들었네요.

단순히 달력 기능입니다. 음력 표시되는...

전체 계획의 극히 일부만 완성된 상태입니다.
계획된 대로 전체 애플리케이션이 완성되면
앱스토어에 올림과 동시에 만들어진 앱의 소스를 가지고
강좌...라기 보다는 어떻게 만들었는지 그 과정을 연재하도록 하겠습니다.

아직 언제 완성이 될지 기약이 없지만 최대한 서둘러서
소기의 성과를 달성하도록 해야겠습니다.

기대해주세요~^^;;;




블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/04/17 04:21



RootViewController.h


@interface RootViewController : UITableViewController {

NSArray *regions;

}

//지역 객체를 담을 배열 선언

@property (nonatomicretain) NSArray *regions;


@end



RootViewController.m


#import "RootViewController.h"

#import "SimpleSectionedTableViewAppDelegate.h"

#import "Region.h"

#import "TimeZoneWrapper.h"


//어떤 경우에 사용되는지  모르겠음…???

NSString *localeNameForTimeZoneNameComponents(NSArray *nameComponents);

NSMutableDictionary *regionDictionaryWithNameInArray(NSString *name, NSArray *array);

@implementation RootViewController


@synthesize regions;


#pragma mark -

#pragma mark View lifecycle

- (void)viewDidLoad {

//Foundation Framework 있는 함수로 NSBundle.h 선언되어있음. Localizable.string 있는 파일에서

//key "Time Zones" 되어있는 값을 가져옴 

self.title = NSLocalizedString(@"Time Zones"@"Time Zones title");

}


#pragma mark -

#pragma mark Table view data source methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

// Number of sections is the number of regions.

//섹션의 수는 regions 배열의 크기를 돌려줌

return [regions count];

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

// Number of rows is the number of time zones in the region for the specified section.

// 섹션에 있는 행의 수는 regions 배열에 들어있는 각각의 region 인스턴스로부터

//TimeZoneWrapper 클래스의 배열인 timeZoneWrappers 크기를 돌려줌

Region *region = [regions objectAtIndex:section];

return [region.timeZoneWrappers count];

}


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

// The header for the section is the region name -- get this from the region

//at the section index.

// 섹션의 제목은 regions 배열의 section 위치에 있는 region 인스턴스로부터 name 속성을 사용함

Region *region = [regions objectAtIndex:section];

return [region name];

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

//cell 재활용을 위해 아이디를 부여

static NSString *MyIdentifier = @"MyIdentifier";


//재활용할 cell 없으면 새로 생성

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];

if (cell == nil) {

cell = [[[UITableViewCell allocinitWithStyle:UITableViewCellStyleDefault 

 reuseIdentifier:MyIdentifier] autorelease];

}

// Get the section index, and so the region for that section.

//NSIndexPath 일련의 배열들의 트리 구조를 표현 하는 것으로 부여되는 값들은 

//각각 다음 단계 배열의 인덱스를 의미한다여기서는 index path section - row 이어지면

//각각 지역 정보를 가지고 있는 regions 배열의 인덱스와 time zone 정보를 가지고 있는

//timeZoneWrappers 배열의 인덱스를 의미한다.

//index path에서 regions 인덱스를 가져와 해당 인덱스의 region 인스턴스를 가져온다.

Region *region = [regions objectAtIndex:indexPath.section];

//regions로부터 가져온 region 인스턴스의 timeZoneWrappers 배열에서 index path

//있는 timeZoneWrappers 인덱스를 가져와 해당 위치의 timeZoneWrapper 인스턴스를 가져온다.

TimeZoneWrapper *timeZoneWrapper = [region.timeZoneWrappers objectAtIndex:indexPath.row];


// Set the cell's text to the name of the time zone at the row

//가져온 timeZoneWrapper 선언된 localeName 속성을  셀의 제목으로 설정한다.

cell.textLabel.text = timeZoneWrapper.localeName;

return cell;

}


#pragma mark -

#pragma mark Table view delegate method

/*

 To conform to Human Interface Guildelines, since selecting a row would have no effect (such as navigation), make sure that rows cannot be selected.

 */

//특정 위치의 셀이 선택되었을   처리 내용이 들어갈 메서드

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

return nil;

}


#pragma mark -

#pragma mark Memory management

//메모리 해제

- (void)dealloc {

[regions release];

     [super dealloc];

}


@end


블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/04/11 10:40



SimpleSectionedTableViewAppDelegate.h

@interface SimpleSectionedTableViewAppDelegate : NSObject <UIApplicationDelegate> {

UIWindow *window;

UINavigationController *navigationController;

NSArray *list;

}


//retain방식으로 객체의 참조를 얻어옴. 자동으로 getter/setter 선언

@property (nonatomicretainIBOutlet UIWindow *window;

@property (nonatomicretain) UINavigationController *navigationController;

//copy방식으로 객체의 참조를 얻어옴. 자동으로 getter/setter 선언

@property (nonatomiccopy) NSArray *list;


@end



SimpleSectionedTableViewAppDelegate.m


#import "SimpleSectionedTableViewAppDelegate.h"

#import "RootViewController.h"

#import "Region.h"



@implementation SimpleSectionedTableViewAppDelegate

//인스턴스 변수들에 대한 getter/setter 구현 자동 생성

@synthesize window;

@synthesize navigationController;

@synthesize list;


//애플리케이션이 구동 완료된 후의 초기화 작업 진행

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Create the navigation and view controllers

//뷰 컨트롤러를 생성하고 생성된 뷰 컨트롤러를 스택의 가장 아래에 놓는 네비게이션 컨트롤러를 생성

RootViewController *rootViewController =

[[RootViewController allocinitWithStyle:UITableViewStylePlain];

UINavigationController *aNavigationController =

[[UINavigationController alloc]initWithRootViewController:rootViewController];

self.navigationController = aNavigationController;


//메모리 해제

[aNavigationController release];

[rootViewController release];

//rootViewController에 지역 정보 설정 (section 설정)

[rootViewController setRegions:[Region knownRegions]];

// Configure and display the window

//윈도우에 네비게이션 컨트롤러 뷰를 추가함

[window addSubview:[navigationController view]];

[window makeKeyAndVisible];

}


//메모리 해제

- (void)dealloc {

[navigationController release];

    [window release];

[list release];

    [super dealloc];

}



@end


블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/04/11 09:00


사용된 메서드 정리


메서드명 : - (NSArray *)componentsSeparatedByString:(NSString *) separator

기능 : separator 구분자로 하여 분리된 배열을 반환함

선언된 클래스 : NSString


메서드명 : + (NSArray *)knownTimeZoneNames:

기능 시스템이 알고있는 모든 time zone의 ID를 문자열 배열로 반환함

선언된 클래스 : NSTimeZone


메서드명 : + (id)timeZoneWithName:(NSString *)aTimeZoneNZme

기능 : 인자로 넘어온 ID와 일치하는 time zone 객체를 반환

선언된 클래스 : NSTimeZone


메서드명 : - (id)initWithKey:(NSString *)keyPath ascending:(BOOL)ascending

기능 : 인자로 넘어온 key path를 정렬기준으로 역시 인자로 넘어온 정렬 순서를 적용하고

   기본 비교 selector를 통해 초기화된 NSSortDescriptor 객체를 반환한다.


          ascending인자가 YES이면 오름차순 NO이면 내림차순 정렬한다.

선언된 클래스 : NSSortDescriptor


메서드명 : - (id)initWithObject:(const id *)object count:(NSUInteger)count

기능 : 인자로 넘어온 C array로부터 count 갯수만큼의 객체를 뽑아 포함시키는 새로운 배열을 할당함

언된 클래스 : NSArray 클래스


메서드명 : -(void)sortUsingDescriptor:(NSArray *)sortDescriptors

기능 : 인자로 넘어온 NSSortDescriptor 객체의 배열을 사용하여 배열을 정렬함.

선언된 클래스 : NSMutableArray


블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/03/21 09:45



SimpleTableView_Prefix.pch


//

// Prefix header for all source files of the 'SimpleTableView' target in the 'SimpleTableView' project

//


#ifdef __OBJC__

    #import <Foundation/Foundation.h>

    #import <UIKit/UIKit.h>

#endif


==================================================================

main.m


int main(int argc, char *argv[])

{

    //자동으로 메모리를 관리할 NSAutoreleasePool 인스턴스 생성

    NSAutoreleasePool * pool = [[NSAutoreleasePool allocinit];


    //애플리케이션 시작

    int retVal = UIApplicationMain(argc, argv, nilnil);


    //pool에 등록된 모든 객체의 메모리 해제

    [pool release];

    return retVal;

}


블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/03/20 09:59 


Hello World 정리

처음으로 맥을 접하고 처음으로 아이폰을 접하고 처음으로 Objective-c를 접해봤다.
아직도 전체적인 구조를 파악할 수 있지는 못하고 다만 단편적인 하나 하나에 대한
의미를 알아가는 단계이기에 부족하기도 하고 또 잘못된 내용도 있을지 모르겠다.
이제 겨우 가장 기초적은 샘플 하나를 분석해 본 것 뿐이므로 많은 기대를 하지
않는 것이 좋겠다. 

특히 인터페이스 빌더의 설명같은 경우 애플리케이션을 구현하면서
공부한 것이 아니라 역으로 이미 만들어진 애플리케이션을 인터페이스 빌더로
열어 확인한 내용이다보니 더더욱 분석하기가 어려웠다.

오늘의 이 내용이 내일 더 나은 결과를 위한 밑거름이 될거라 생각하며
첫 예제 분석에서 중요하다고 생각되는 몇가지를 정리하면서 분석을 마친다.


NSAutoreleasePool : 
메모리 자동 관리를 위한 클래스. 
NSAutoreleasePool의 인스턴스가 생성되고 release되는 블럭 사이에서 팩토리 함수로 생성한
대부분의 객체 또는  autorelease 메시지를 받은 객체들은 모두 NSAutoreleasePool가
관리를 하게 되며 NSAutoreleasePool의 인스턴스가 release되는 순간 NSAutoreleasePool이
관리하던 모든 객체들이 메모리에서 해제된다.
최초 main.m에 자동 코딩되는 내용은 지우지 않는 것이 좋다.

UIApplicationMain :
UIKit 프레임워크에 선언된 함수로 main.m 내에서 호출되어 애플리케이션을 객체를 생성하고
위임(delegate)하며 이벤트 사이클을 설정한다.

아이폰의 애플리케이션은 기본적으로 이 함수 호출로부터 시작한다.

delegate : 
애플리케이션이 객체간 메시지를 전달하는 방법 중 하나
많은 UIKit 프레임워크의 클래스들이 delegation을 사용한다.
사용자로부터 어떤 액션을 받게 되면 그 액션에 대한 내용을 delegate 프로토콜을 구현한 
클래스로 넘기게 되고 이 클래스에서 실제로 어떤 응답을 처리해야 할지 구현하게 된다.

Hello World 샘플의 경우 다음과 같은 delegation이 이루어지고 있다.

UIApplication에 대한 delegation
HelloWorldAppDelegate.m은 UIApplicationDelegate프로토콜을 사용하고 있는데
UIApplicationDelegate는 UIApplication에 대한 delegate 프로토콜이며 애플맄이션의 실행과
종료, 메모리 부족에 대한 경고, URL 리소스의 사용, status-bar의 방향 변경 및 
기타 시스템 관련 이벤트를 처리한다.

UITextField 대한 delegation
MyViewController.m은 UITextFieldDelegate프로토콜을 사용하고 있으며
이것은 UITextField에서 발생하는 이벤트에 대한 응답 처리를 담당한다.
textFieldShouldReturn는  이 프로토콜에서 정의된 함수로 텍스트필드에서
return키가 입력되었을 경우의 이벤트를 처리한다.

UIResponder :
이벤트에 대한 응답 처리를 위한 인터페이스를 정의한 클래스.
UIApplication이나 UIView와 같은 클래스들의 부모 클래스이고 이 예제에서 사용된
MyViewController의 부모클래스인 UIViewController클래스도 UIResponder를 상속받고 있다.

일반적으로 터치(touch) 이벤트와 동작(motion) 이벤트 2가지가 있는데
MyViewController에 구현된 touchesBegan 함수는 이 UIResponder에 선언된 함수고
화면상에 한 개 이상의 손가락이 눌렸을 때의 이벤트를 처리한다.

protocol : 
다중 상속 처리를 위한 함수 선언들의 집합체로 java의 interface와 유사하다.
Objective-c는 기본적으로 다중 상속이 불가능한데 protocol은 2개 이상을
사용할 수 있다.

기본적으로 프로토콜을 사용한 클래스에서는 프로토콜에 선언한 함수를 모두 구현해야 하나
다음의 옵션으로 선택적으로 구현 가능하다.

@optional : 구현하지 않아도 됨
@required : 반드시 구현해야 함
키워드 없음 : 반드시 구현해야 함

Hello World 예제의 MyViewController에서 사용된 UITextFieldDelegate 프로토콜은
모든 함수들이 @optional로 지정되어있어 이 예제에서는 textFieldShouldReturn함수
하나만 구현되어있다.

property :
@property 키워드는 접근자(accessor. getter)와 변경자(mutator, setter)를 
자동으로 생성해준다.

선언부(.h파일)에 @property로 변수를 지정해 놓으면 별다른 접근자 함수 선언 없이
구현부(.m파일)에 접근자 함수를 구현할 수 있다.

더욱 간편하게는 선언부에서 @property로 지정한 변수에 대해 구현부에서
@synthesize키워드를 이용해 지정해 놓으면 함수 구현까지 자동으로 이루어진다.

@class :
어떤 클래스에서 참조하여 사용하고자 하는 클래스를 지정할 때 사용하는 키워드
일반적인 #import와 다른 점은 #import가 이미 참조할 클래스의 선언부가 필요한 반면
@class로 지정을 해 놓으면 실제적인 클래스 선언 없이 클래스 이름만으로 해당 클래스를
사용하겠다고 컴파일러에게 알려줄 수 있다.

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/03/07 09:22



main.m


#import <UIKit/UIKit.h>


int main(int argc, char *argv[])

{

    NSAutoreleasePool * pool = [[NSAutoreleasePool allocinit];

    int retVal = UIApplicationMain(argc, argv, nilnil);

    [pool release];

    return retVal;

}


UIApplicationMain : 일반적인 iPhone 유저 인터페이스를 보여주기 위해, 유저 인터페이스 프레임워크를 실행하는 코드를 지님
(모든  iPhone  애플리케이션은 main 함수에서 UIApplicationMain 함수를 실행해야 함)

  (1) UIApplication 객체와 애플리케이션 델리게이트 객체(HelloAppDelegate)를 생성
  (2) UIApplication 객체에 델리게이트 객체를 연결
-> UIApplication 객체가 자신이 참조하는 델리게이트 객체에게 메시지를 보냄
-> 델리게이트 객체가 보내진 이벤트 처리 코드를 수행

[출처] 아이폰 기초 3. |작성자 일리


NSAutoreleasePool : 자동 해제 풀( auto release pool)을 관리하는 객체
  개발자가 직접 메모리 관리를 제어하기 어려운 상황인 경우 자동으로 메모리 관리를 해주는 클래스.
  release pool 객체에 메모리 관리를 할 객체들을 저장하고 release pool 객체가 해제될 때 저장된
  객체들의 메모리를 모두 해제함.

  이 메인 함수의 경우 UIApplicationMain auto release 처리한 객체들을 모두 pool에서
  관리하게 되는 것이다.

HelloWorld_Prefix.pch


#ifdef __OBJC__

    #import <Foundation/Foundation.h>

    #import <UIKit/UIKit.h>

#endif


기본 Framework  사용을 위한 헤더파일들을 전처리기에서 처리하도록 함

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/03/07 08:30





* Classes : 모든 오브젝티브C 클래스들이 위치하는 곳, 우리가 작성할 코드

 

* Other Sources : Objective-C가 아닌 소스코드

   - 프로젝트네임_Prefix.pch : (PreCompiledHeader) 프로젝트에서 사용하는 외부 프레임워크의 헤더 파일 목록

   - main.m : 어플리케이션의 main() 메서드

 

* Resources : 어플리케이션의 일부로써 아이콘 이미지, 다른 이미지, 소리파일, 동영상 파일,

                     텍스트파일, 프로퍼티 리스트등을 포함

   - 프로젝트네임ViewController.xib : 인터페이스 빌더에서 사용하는 정보

   - 프로젝트네임-info.plist : 어플리케이션 정보를 담는 프로퍼티 리스트

   - MainWindow.xib : 어플리케이션의 기본 인터페이스 빌더 (또는 "nib") 파일

 

* Framework : 코드와 자원이 담긴 라이브러리, 이 폴더에 추가한 프레임 워크나 라이브러리는

                     어플리케이션에 링크되고, 코드에서 그 프레임워크나 라이브러리의 객체, 함수, 자원

                     을 사용 가능.

 

* Products : 프로젝트가 컴파일해서 생성한 어플리케이션, 프로젝트네임.app가 결과물

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^

최초 작성일 : 2010/03/06 09:44


ReadMe.txt


### HelloWorld ###


================================================================================

설명:

HelloWorld is a sample application that demonstrates the use of a text field to enter text using a keyboard, and a text label to display text.


HelloWorld presents a simple interface. When the application launches, it displays a navigation bar containing a text field. Tap on the text field to enter your name. Tap the Done button on the keyboard to dismiss the keyboard. The application then displays in a label what you typed in the text field.


The basic features of the application are discussed in more detail in "Your First iPhone Application" in the Reference Library <http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/>.


HelloWorld는 키보드를 이용하여 text field에 text를 입력하는 기능과 text를 표시하기 위한 text label을 보여주기 위한 샘플 애플리케이션이다.


HelloWorld는 간단한 인터페이스를 보여준다. 애플리케이션이 시작되면 text field가 포함된 navigation bar가 표시된다.이름을 입력하기 위해서는

text field를 터치하면 된다. 키보드에 있는 Done 버튼을 터치하면 키보드가 가려지게 된다. 이후 이 애플리케이션은 text field에 입력한 문자열을

label에 표시한다.


이 애플리케이션의 기본적인 특징들은 Reference Library <http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/>

에 있는 "Your First iPhone Application"에서 보다 상세하게 토론할 수 있다.


================================================================================

BUILD 요구사항:


Mac OS X 10.5.3, Xcode 3.1, iPhone OS 2.0


================================================================================

RUNTIME 요구사항:


Mac OS X 10.5.3, iPhone OS 2.0


================================================================================


PACKAGING LIST

HelloWorldAppDelegate.m

HelloWorldAppDelegate.h

The UIApplication object's delegate. On start up, this object receives the applicationDidFinishLaunching: delegate message; this creates a view controller and sets the window's view to the view controller's view.


UIApplication object's delegate. 애플리케이션 실행시 이 객체는 applicationDidFinishLaunching: delegate 메시지를 받고

뷰 컨트롤러를 생성한 후 뷰 컨트롤러 뷰 위에 윈도우 뷰를 설정한다.


MyViewController.m

MyViewController.h

A view controller that loads the HelloWorld nib file that contains its view.


자체 뷰를 가지고 있는 HelloWorld nib 파일을 로드하는 뷰 컨트롤러


MainWindow.xib

The nib file containing the main window.


메인 뷰를 가지고 있는 nib파일


HelloWorld.xib

The view controller's nib file.


뷰 컨트롤러의 nib파일



================================================================================

CHANGES FROM PREVIOUS VERSIONS:


Version 1.7

- Updated for and tested with iPhone OS 2.0. First public release.


Version 1.6

- Updated for Beta 7.


Version 1.5

- Updated for Beta 6.

- Updated the user interface to match Human Interface Guidelines.

- Tapping on the view outside the text field dismisses the keyboard.


Version 1.4

- Updated for Beta 5.

- Made minor changes to project file -- added ReadMe, removed project-level override for ALWAYS_SEARCH_USER_PATHS, added override at target level.

- Renamed -sayHello: to changeGreeting: to clarify effect.

- Removed Visible At Launch flag from window in MainWindow.xib; added [window makeKeyAndVisible] in application delegate.


Version 1.3

- Updated for Beta 4.

- Uses a nib file to create the user interface -- most of the application code is replaced.

- Uses a view controller to set up the view.


Version 1.2

Replaced the background default.png images with ones that do not have a custom text field drawn on them.

Version 1.1

Added pointer to the iPhone Reference Library.

Return key on keyboard now functions.


Copyright (c) 2008 Apple Inc. All rights reserved.

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^