iPhone/팁&태크2009/02/27 20:57

   안녕하세요. 써드파티어플 소개, 그 두 번째 시간입니다. 오늘 소개해 드릴 써드파티어플은 MxTube입니다. Mxtube는 유튜브 동영상을 검색해서 실시간으로 볼수 있고 원하는 동영상을 터치 내로 다운로드 할 수 있는 기능을 가진 어플리케이션입니다. 그럼 지금부터 설치를 시작해보도록 하겠습니다.

   다음 그림과 같이 Cydia에서 MxTube를 설치합니다.


사용자 삽입 이미지

   MxTube를 실행하면 다음과 같은 화면을 볼 수 있습니다.


사용자 삽입 이미지

   이제 Search로 들어가서 원하는 동영상을 찾아보겠습니다. 전 요즘 소녀시대의 태연씨가 귀여워 보여서 '태연'으로 검색해보았습니다. 다음 그림과 같이 여러가지 동영상이 검색되는 걸 확인할 수 있습니다.


사용자 삽입 이미지

   검색된 결과 중에서 하나를 선택하면 위의 그림에서 보는 것과 같이 Stream을 할 것인지 Download를 할 것인지 묻는 창이 나옵니다. 전 바로 Download를 선택해 보겠습니다. 아래 그림에서 보는 것처럼 여러가지 선택사항들이 보입니다. 전 이중에서 High(Wifi)를 선택해서 다운로드를 받아보겠습니다. 선택을 하게되면 아래 그림처럼Downloads에 빨간색으로 1이라는 숫자가 표시되는 것을 볼 수 있습니다. 현재 다운로드 하고 있는 항목이 1개 있다는 것을 말해줍니다. Downloads에 들어가면 현재 다운로드중인 동영상을 볼 수 있습니다.


사용자 삽입 이미지

   다운로드가 완료되면 아래 그림처럼 Videos에 저장된 동영상이 나열되어 있는 것을 볼 수 있습니다. 이 동영상이 저장되는 경로는 private/var/mobile/media/mxtube/ 이니 컴퓨터에 저장하고 싶다면 이 경로로 찾아가서 복사를 해주시면 되겠죠?

     
사용자 삽입 이미지


   이 어플리케이션은 소장하고 계속 보고 싶은 동영상을 쉽게 iPod touch에 저장하고 무선랜이 되지 않는 곳에서도 저장해놓은 동영상을 볼 수 있다는 장점이 있습니다. 또 이 어플리케이션을 이용하여 동기화과정이 필요한 아이튠즈를 쓰지 않고 MxTube 동영상이 저장되는 경로에 바로 보고 싶은 동영상을 집어넣어서 볼 수도 있습니다. 저 같은 경우는 춤을 배우고 싶을 때 이 어플리케이션을 유용하게 쓰고 있답니다. 요즘 예뻐보이는 소녀시대 태연씨의 노래를 제 iPod touch에 넣어두고 자주 듣고 볼 수 있으니 여간 좋은게 아닌 것 같네요. 여러분들도 한 번 써보시길 권장합니다. 감사합니다.
Posted by 뽀뎅

Leave your greetings.

iPhone/팁&태크2009/02/14 16:17

   2월초부터 iPod touch 2G 해킹 Lite version의 등장으로 인해 각 커뮤니티 사이트들이 들썩였습니다. 실시간 접속자수는 평소의 수 배에 달할 정도였고, 올라온 강좌를 보며 해킹을 시도하는 사람들로 커뮤니티 사이트는 북새통을 이루었습니다. 왜 사람들이 해킹에 이렇게 관심을 보이는지, 그 이유와 현재 나와 있는 몇 가지의 해킹 방법을 소개하겠습니다.

   2007년 6월 무렵 iPhone 2G가 출시되었고, 2007년 9월 무렵 iPod touch 1G가 출시되었습니다. (앞으로는 부르기 쉽게 iPhone은 아이폰으로 iPod touch는 터치로 부르겠습니다.) 그 당시에는 현재와 같은 App Store가 존재하지 않았기 때문에 원하는 어플리케이션을 설치할 수 없었습니다. 버전이 업그레이드 되면서 몇 가지의 어플리케이션이 추가되었습니다만 아이폰 사용자는 무료로 사용할 수 있었던것에 반해 터치 사용자는 새로 나온 어플리케이션을 9.99달러를 주고 사야만 했습니다. 또 사용자가 원하는 기능이 충분히 제공되지 않았고, 사용자들은 이런 훌륭한 하드웨어에서 다양한 소프트웨어를 사용하지 못하는 것을 안타깝게 여겼습니다. 이런 이유들로 인해서 그때 당시의 해킹을 통해 다양한 소프트웨어를 설치하려는 시도를 하게 됩니다. 터치 2G(2.0 버전)이 나오기 전에는 한글 입력이 지원 되지 않아서 해킹을 통해서 한글 입력이 가능하도록 만들기도 했습니다. 이것은 한국 사용자들에게는 더욱 더 절실했었습니다.

   이런 사용자들의 큰 니즈에 따라, 해커라 불리우는 사람들과 프로그래머들은 '자일 브레이크'(소위 말하는 해킹)를 통해서 아이튠즈 외의 방법을 통해서는 접근이 불가능한 메모리 영역의 접근이 가능하게 했습니다. 해킹후에는 Installer나 Cydia라는 특수한 어플리케이션을 설치할 수 있었습니다.


   하지만 이러한 해킹 추세에도 큰 변수가 찾아왔습니다. 2008년 6월 무렵 아이폰 3G와 터치 2G(2.0 버전)이 출시된것과, App Store의 시작입니다. App Store의 출시로 인해 해킹없이도 좋은 퀄리티의 게임과 어플리케이션의 설치가 가능해졌습니다.



사용자 삽입 이미지


   이제 해킹을 하지 않아도 수많은 어플리케이션을 설치할 수 있게 해준 App Store의 등장은 해킹의 의미 자체에 영향을 주었습니다. 단순히 App Store 출시 허가를 받지 못한 어플리케이션을 깔기 위한 수단이 되었고, 크랙된 불법 어플리케이션을 사용하기 위한 경로로 그리고 정상적인 방법으로는 할 수 없는 바탕화면 바꾸기라던가, 테마 적용 등을 위해 해킹을 시도하고 있습니다.

다음은 해킹을 통해 바탕화면의 테마를 바꾼 모습입니다. 정상적인 방법으로는 이런 것을 할 수 없습니다.

사용자 삽입 이미지

폴더 기능도 기본적으로 제공되지 않지만, 해킹을 통해서는 가능합니다.

사용자 삽입 이미지


   그럼 이번에는 많은 해킹 방법 중, 잘 설명되고 초보자도 조금만 이해하고 숙지하면 해킹할 수 있는 두 가지의 해킹 방법을 제공하는 사이트를 정리해보겠습니다.


1. EasyHacker2.0 쉽게 해킹&부팅 하기 코드삽입필요없음 (2.1패치!!필요!!)(xp전용)
[출처] EasyHacker2.0 쉽게 해킹&부팅 하기 코드삽입필요없음 (2.1패치!!필요!!) (아이팟터치 유저들의 공간) | 작성자 생명의힘(queenyjina) | http://cafe.naver.com/appletouch.cafe?iframe_url=/ArticleSearchList.nhn%3Fsearch.clubid=14817810%26search.searchtype=1%26search.query=해킹%20이유%26search.articlemedia=0%26search.sortby=date%26search.searchdate=all%26search.page=5


사용자 삽입 이미지

사이트 특징
ㄱ. 각각의 절차에 대한 사진과 설명을 착실하게 담았다.
ㄴ. 사용자의 조작을 최소화했다.
ㄷ. 동영상 강의를 이용하여 혼란이 갈 수 있는 부분에 대해 쉽게 설명했다.


2. redsn0w GUI 버전
[출처] redsn0w GUI 버전(아이팟터치 유저들의 공간) | 작성자 조리뽕(misoro_) | http://cafe.naver.com/appletouch.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=229320




사용자 삽입 이미지


특징
ㄱ. 콘솔창이 아닌 그래픽을 가지고 설명함으로써 사용자의 이해를 도왔다
ㄴ. 사용자의 조작을 최소화했다.
ㄷ. 한국어버전이 아니라는 점이 아쉽다. 하지만 해킹에 관심이 있다면 각각의 메뉴가 무엇인지는 한 눈에 알아볼 수 있다. 또, 1번 방법과는 다르게 DFU모드로의 진입에 대한 설명이 조금 부족하다.


마치는 글.
   자일 브레이크(해킹)는 불법이 아닙니다. (배포와 하는 행위 모두) 하지만 크랙 어플리케이션을 쓰는 것은 불법입니다. 아직도 많은 곳에서는 자신만의 아이폰/터치를 만들어서 사용하기를 원하는 순수한 사용자들이 많고 App Store에서는 접할 수 없는 갖가지 기능의 어플리케이션이 존재하기 때문에 해킹이 무조건 나쁘다고 할 수는 없을 것 같습니다. 하루 빨리 Apple에서 어플리케이션에 대한 개발자들의 '창작의 자유'를 무한으로 확장 시켜주어 사용자들의 선택의 범위를 넓혀주었으면 좋겠습니다. 하지만 해킹은 시스템 고장의 큰 원인이 될 수 있기 때문에 가급적이면 크랙 어플리케이션의 사용은 자제하고 정상적인 사용을 해야 할 것입니다.
   다음에는 써드파티어플을 소개해드리도록 하겠습니다. 감사합니다.

ps. 네이버 '아이팟터치 유저들의 공간' 카페의 별빛속에(339kio)님의 글에서 상당부분 발췌했습니다. 감사드립니다.

Posted by 뽀뎅

Leave your greetings.

iPhone/기획2009/02/14 11:21

앞으로 매주 한가지의 아이폰 어플리케이션을 소개해드리려고 합니다. 선정 기준은 제가 사용해본 어플리케이션 중 재미있게 했거나, 독특한 아이디어가 번뜩이거나, 제 생활에 도움이 되는 어플리케이션입니다. 지극히 주관적인 관점에서 분석하여 소개드릴 것이니 참고로만 보시기 바랍니다.

이번주에는 AppStore 에서 유료/무료 모두 많은 인기를 얻고 있는 게임인 iShoot 에 대해서 소개해 드리겠습니다.  이 게임은 제가 5일 동안 지하철 이동중에 푹 빠져서 했던 게임이고, Lite 버전을 무료를 처음에 시작했다가 재미 있어서 유료 버전까지 구매해서 즐겼던 게임입니다.

         


iShoot은 2000년 경에 인기를 얻었던 포트리스를 재미있게 해본 유저라면 쉽게 매력에 푹 빠질 수 있는 게임입니다. 포트리스가 다양한  캐릭터와 아기자기한 그래픽 등으로 국내 유저들에게 많은 사랑을 받았다면 iShoot은 단순한 조작과 다양한 무기 사용이 매력적입니다.

먼저 New Game을 선택하면 게임의 레벨, 플러이어 수, 라운드 수를 정할 수 있습니다. 화면과 같이 사람과 컴퓨터가 대결하는 게임으로 아직 네트워크를 통한 사람대 사람은 지원하지 않습니다. 하나의 아이폰을 이용하여 4명까지 같이 게임을 즐길 수 있고, 컴퓨터 인공지능이 꽤 쓸만하게 만들어 졌기 때문에 재미있게 플레이할 수 있습니다. Difficulty를 통해 게임의 난이도를 지정할 수 있는데, iShoot 을 저음 해 보는 분이라면 게임의 감을 익히고 다양한 무기 경험을 위하여 Easy 부터 할 것을 권해 드립니다.


게임의 조작은 매우 쉽고 간단 합니다. 다음 화면처럼 화면의 빈 공간을 터치하여 각도를 조절할 수 있습니다.


하단의 FIRE 버튼을 눌러서 게이지 조절을 하여 무기를 발사 할 수 있습니다.


위 그림의 좌측 상단의 Wind 는 실제로 포탄이 날아가는데 큰 영향을 주지 않는 것 같습니다.. 포트리스의 소위 빽샷(?)에 묘미를 느끼셨던 분들은 아쉽지만 이 게임을 통해 재현해내지는 못할 것 같습니다.


게임의 특징 중 한가지는 상점에서 무기를 살 수 있다는 것입니다. 다양한 무기는 게임의 재미를 한층 강화 시켜 줍니다.  유료 버전과 무료 버전의 가장 큰 차이가 여기서 나타납니다. 무료 버전에서는 6개의 무기만 고를 수 있는데 반해 유료 버전에서는 25 개의 다양한 무기를 선택 할 수 있습니다.













유로 버전에서 볼 수 있는 다양한 무기들 입니다. 무기가 게임의 재미에 가장 큰 영향을 끼치기 때문에, 많은 무기들 중에 강력한 몇 가지만 소개해 보겠습니다. 그 첫 번째로 Shiva Bomb 입니다. 힌두교의 한 신의 이름에서 따온 것으로 추정되는 이 미사일은 iShoot의 무기중에 가장 강력한 파괴력을 자랑합니다. 시험삼아 탱크 바로 앞에 발사를 해 보았는데 그 일대가 말끔하게 사라지고 말았습니다. 무기가 비싸기는 하지만 성능 과연 최고입니다.
 





두번째는 Vulcan Cannon 입니다. 바로 앞에 적이있을 때 매우 유용한 무기로 엄청나게 많은 포탄을 발사하여 상대 탱크를 한방에 보내줍니다.





세번재로는 Meltdown 과 Grandslam 입니다. 주변의 땅을 깍아내리는데 굉장한 능력을 보여주는 무기로 상대 탱크에 직격으로 맞았을 때도 강력한 파괴력을 발휘합니다.


다음은 Grandslam을 발사한 모습입니다.





다음은 Meltdown을 발사한 모습입니다.




이 외에도 많은 무기들이 있지만 다른 무기들은 게임을 직접 하면서 느껴 보는게 훨씬 재미 있을 것입니다. 마지막으로 유료 버전과 무료 버전의 다른 기능을 소개하겠습니다. 무료 버전에서는 탱크를 이동시킬 수 없지만, 유료 버전에서는 탱크를 이동시킬 수 있습니다. 하단의 무기선택 영역에서 Fuel 라는 것이 나오면 주어진 연료를 가지고 탱크를 이동 할 수 있습니다.







이 게임은 빠른 진행으로 한판 한판이 굉장히 빨리 끝나게 됩니다. 따라서 지하철이나 버스에서 아주 짧은 시간동안 몰입하기에 좋은 게임입니다.  그리고 다양한 무기의 구성은 다른 무기를 사용해보고 싶은 욕망을 적절히 자극 해 주어 쉽게 질리지 않게 합니다. 가장 아쉬운 점은 역시 네트워크로 친구와 게임할 수 없다는 것 입니다. 친구들과 함께 게임할 수 있다면, 더욱 재미 있으리라 생각합니다.

팁. 지형을 포탄으로 모두 제거하면 하단의 컨트롤 바가 지형으로 새롭게 인식되는 버그가 있으니 게임을 하면서 적절히 활용하세요.
팁2. 저는 무료 버전과 유료 버전에서 재미의 차이를 느끼지 못했습니다.



 

Posted by 부르주아

Leave your greetings.

  1. 헉 이건 포트리스와 웜즈의 원조인... 스코치? 던가 그 386때 게임하고 비슷하네요. 정말 재미있게 했었엇는데... 포스팅 감사드립니다^^

    2009/12/13 13:16 [ Permalink : Modify/Delete : Reply ]

iPhone/팁&태크2009/02/14 04:16


Object-C 에서의 메서드 구현에는 정확히 딱 두가지가 있는것 같습니다.

바로 Class Method와 Instance Method인데요. 이 두가지 메서드는 Java로 따져보면 static 메서드와 일반 메서드로 구분될 수 있겠다고 생각합니다.

우선 테스트 코드를 작성하기 위해 Mac OS X이하의 Command Line UtilityFoundation Tool 프로젝트를 생성합니다.

보통 C++하실때 보는 콘솔 어플리케이션쯤으로 생각하시면 되겠네요.

우선 MethodTest라는 Object-C 클래스를 추가합니다.

MethodTest.h
#import <Cocoa/Cocoa.h>

@interface MethodTest : NSObject {

}
+ (void)printWithClassMethod;
- (void)printWithInstanceMethod;

@end

MethodTest.m
#import "MethodTest.h"

@implementation MethodTest

+ (void)printWithClassMethod {
NSLog(@"Running with class method");
}
- (void)printWithInstanceMethod {
NSLog(@"Running with instance method");
}

@end

이제 main 함수에 다음과 같이 기록해 봅시다.
#import <Foundation/Foundation.h>
#import "MethodTest.h"

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// insert code here...
[MethodTest printWithClassMethod];
MethodTest *mt = [MethodTest alloc];
[mt printWithInstanceMethod];

[pool drain];
return 0;
}

감이 오시나요? printWithClassMethod는 클래스를 인스턴스화 하지 않고도 호출할 수 있는 메서드입니다.

하지만 printWithInstanceMethod는 꼭 초기화 된 상태에서 호출해야만 하죠.

이를 자바로 한번 풀어보면 다음과 같겠죠.
class MethodTest {
public static void printWithClassMethod() {
System.out.println("Running with class method");
}
public void printWithClassMethod() {
System.out.println("Running with instance method");
}
}

Class Method와 Instance Method의 차이 이해 되시죠? ^^

Posted by 아이

Leave your greetings.

iPhone/팁&태크2009/02/14 04:14






 

Object-C의 특별한 문법 때문에 처음 접근이 어려우신 분들을 위해 간단하게 문법을 비교하여 보았습니다.

Messages
일반적으로 객체의 메서드를 호출하는 것을 Object-C에서는 메세지라고 표현합니다.

특정 객체의 메서드를 호출하는데 Java나 C++에서는 다음과 같이 표현합니다.

// Java
obj.method(parameter);

// C++
obj->method(parameter);

하지만 Object-C에서는 다음과 같이 표현합니다.
// Object-C
[obj method:parameter];

처음 볼때는 정말 어색했는데 자꾸 보다 보니깐 이제 좀 괜찮은거 같습니다. 오히려 소스코드를 볼때 메서드라고 확 튀어 보이니 더 좋은것 같기도 하네요.

Interface
Object-C에서 말하는 Interface 지시자는 Java나 C++에서 말하는 Class를 뜻합니다. 정확히는 선언부분만이라고 말해야겠군요.

좀더 정확히 말해보자면 메서드의 시그네이쳐를 선언해 둔다는 관점에서 Java에서 말하는 Interface와 비슷할 수도 있겠네요.

C++에서는 헤더파일안에 클래스의 선언부분과 같을 수 있겠고요. 구현부분은 .m 파일에서 합니다.

그렇다면 마찬가지로 Java와 C++의 예제 소스 코드를 보도록 할까요?
// Java
class classname extends superclassname {
// instance variables
int memberValue;

// member methods
return_type method1(param1_type param1, param2_type param2) { ... }
return_type method1(param1_type param1, param2_type param2) { ... }
}

// C++
class classname : superclassname {
// instance variables
int memberValue;

// member methods
return_type method1(param1_type param1, param2_type param2);
return_type method1(param1_type param1, param2_type param2);
}

Java의 예는 클래스의 구현부분이 클래스에 포함됩니다. Java의 Interface와 비교를 해볼려니 억지같고 추상클래스를 만들자니 또 억지 같아서 그냥 저렇게 써두었습니다.

그럼 Object-C의 구현 부분을 한번 볼까요?
// Object-C
@interface classname : superclassname {
// instance variables
int memberValue;
}

// member methods
- (return_type)method1:(param1_type)param1 param2_varName:(param2_type)param2;
- (return_type)method1:(param1_type)param1 param2_varName:(param2_type)param2;
@end

어떤가요? 이해가 되시나요? 그렇다면 이제 클래스의 구현부를 보도록 하겠습니다.

Implementation
Java의 경우에는 클래스 내부에서 그냥 메서드가 구현되었다고 치고 C++의 예를 한번 살펴 보겠습니다.
// C++
return_type classname::method1(param1_type param1, param2_type param2) {
...
}

return_type classname::method1(param1_type param1, param2_type param2) {
...
}

Object-C의 문법도 한번 볼 차례군요.
// Object-C
@implementation classname
- (return_type)method1:(param1_type)param1 param2_varName:(param2_type)param2 {
...
}
- (return_type)method1:(param1_type)param1 param2_varName:(param2_type)param2 {
...
}
@end


Instantiation
Object-C 에서는 객체를 생성하는 방법또한 독특한 느낌을 가지고 있습니다. 마찬가지로 비교를 한번 해볼까요?
// Java
MyObject obj = new MyObject();
obj.init();

// C++
MyObject *obj = new MyObject();
obj->init();

자 그렇다면 Object-C에서는 어떻게 하는지 알아볼까요?
// Object-C
MyObject *obj = [MyObject alloc];
[obj init];

혹은 다음과 같이 한줄로 사용할 수도 있습니다.
// Object-C
MyObject *obj = [[MyObject alloc] init];

어떤가요? 굉장히 색다른 느낌인가요?

지금까지 제 생각에 일반 프로그래밍 언어와 가장많이 다른 부분을 정리해 보았습니다. 이정도면 처음 Object-C를 봤을때의 혼란을 줄어들지 않을까 싶네요.

더 공부해 보고 싶으신 분은 [이곳]을 참고해 보시면 애플에서 잘 정리한 문서를 제공하고 있으니 참고하시면 되겠네요.

이글은 http://theeye.pe.kr/entry/compare_object_c_with_java_and_c 에서도 볼 수 있습니다.
Posted by 아이

Leave your greetings.

iPhone/팁&태크2009/02/14 04:05
Object-C는 아이폰 개발에 사용되는 언어입니다.

C와 C++의 중간 개념이라고들 하던데 확실히 C언어에 객체의 개념을 추가하고 적절한 라이브러리가 추가된 모습이더군요.

공부하면서 한번 정리를 해보도록 하겠습니다.

객체를 생성하기 위해 클래스를 선언하는데 일반적으로 C++을 해보셨던 분들이 이해하기 좀 어려운 모습을 가지고 있습니다.

XCode에서 New -> New File 항목에서 Object-C Class를 선택하여 클래스 파일을 추가합니다.

Foo 라는 클래스를 만들어 보면 Foo.h와 Foo.m 파일이 생성됩니다.

Foo클래스에 변수와 메서드들을 추가해 봅시다. 다음과 같은 방법으로 합니다.

Foo.h
@interface Foo : NSObject {
IBOutlet NSTextField *textField;
}
- (IBAction)seed:(id)sender;
- (IBAction)generate:(id)sender;
@end

Interface라는 이름을 가지고 선언하긴 하지만 엄연히 클래스를 선언하는 구문입니다.

Foo라는 클래스는 NSObject를 상속받았습니다. NSObject는 NextStep에서 만든 최상위 클래스입니다.

모든 NS로 시작하는 클래스들은 모두 최상위로 NSObject를 상속받습니다. 마치 자바의 Object와 같네요.

또한 NSTextField형의 textField라는 이름의 인스턴스변수(맴버변수)를 선언하였습니다.

IBOutlet은 외부의 다른 객체를 가리킬수 있는 변수를 뜻합니다.

추후에 올려보겠지만 UI상의 컴포넌트 객체들과 변수를 연결할 수 있습니다.

또한 -로 시작하는 줄들은 메서드들입니다. seed메서드만 보면 IBAction을 반환하고 id타입의 sender를 첫번째 인자로 입력 받습니다.

위의 클래스를 구현하면 다음과 같이 합니다.

Foo.m
@implementation Foo

- (IBAction)seed:(id)sender {
...
}
- (IBAction)generate:(id)sender {
...
}

위와 같이 메서드의 몸체를 구현할때 맴버 인스턴스 변수인 textField에 마음껏 접근할 수 있습니다.

객체 자기 자신을 가르킬 경우에는 자바나 C++에서는 this를 사용하지만 여기서는 self를 사용합니다.

인자를 받을 넘길때도 특이한점이 있군요. 두개 이상의 인자를 받을경우에는 굉장히 복잡해 집니다.
- (int)addNumbers:(int)left rightNumber:(int)right {
return left + right;
}

위와 같은 메서드는 addNumbers:rightNumber: 라고 부릅니다. 보통의 프로그래밍을 하던 느낌으론 굉장히 의문이 가는 부분입니다.

addNumbers는 int형 값을 반환하는 메서드입니다. 첫번째 인자는 int형 left 변수입니다.

그렇다면 rightNumber는 저게 뭘까요.  보통 인자를 가진 메서드를 셀렉터(Selector)라고 부릅니다.

위의 코드를 이렇게 바꿔 보면 이해가 쉬울것 같네요.
int addNumbers(int left, int right) {
return left + right;
}

실제로 사용되는 인자의 이름은 left, right이지만 rightNumber와 같은 식의 나누어진 셀렉터를 사용하여 메서드의 인자의 역할을 더욱 분명히 할 수 있는 장점(?)이 있습니다.

이제 함수를 호출하는 방법을 알아보겠습니다.
NSMutableArray *array = [NSMutableArray alloc];

Object-C에서 메서드 호출을 메세지를 보낸다고 표현합니다. 위의 경우에는 다음과 같이 생각하시면 될 것 같네요.
NSMutableArray array = new NSMutableArray();

위와 같이 동적으로 메모리를 잡고 array변수로 가리키게 합니다. 이제 초기화 하는 init 메세지를 보내보겠습니다.
NSMutableArray *array = [NSMutableArray alloc];
[array init];

array는 리시버(receiver)라고 합니다. 이 리시버에 init메세지를 입력합니다.

다음과 같이 위의 두줄을 한줄로 사용할 수도 있습니다.
NSMutableArray *array = [[NSMutableArray alloc] init];

인자를 입력할 경우에는 다음과 같이 사용합니다.
[array addObject:foo];

다수의 인자를 입력할때는 다음과 같은 방법으로 합니다.
[array insertObject:foo atIndex:bar];

위에서 언급했듯이 insertObject는 메서드명이기도 하면서 변수를 가리키는 셀렉터이기도 합니다.

Posted by 아이

Leave your greetings.

iPhone/강좌2009/02/13 16:23
Event Handling

iPhone의 운영체제는 기본적으로 멀티 터치를 지원합니다. iPhone은 기존에 사용자가 이용하던 마우스나 키보드를 벗어나, 화면에 보이는 객체를 자유 자재로 선택하여 조작할 수 있는 환경을 제공합니다. 이러한 터치 이벤트는 다음과 같이 크게 3가지로 분류되어 view에서 메시지를 수신하여 처리할 수 있습니다.

* touchesBegan
prototype:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에 손가락을 대면 호출됩니다.

* touchesEnded
prototype:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에서 손가락을 떼면 호출됩니다.

* touchesMoved
prototype:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
설명:
사용자가 화면에 손가락을 대고 드래그 동작을 하면 호출됩니다.

iPhone에서위와 같은 이벤트가 호출되는 순서를 그림으로 나타내면 다음과 같습니다.

사용자 삽입 이미지

사용자가 손가락 1개를 화면에 터치 하였을 때 UITouchPhaseBegan, 즉 touchesBegan 메시지를 수신하고 또 다른 손가락이 터치 되었을 때 다시 한번 touchesBegan 메시지가 수신됩니다. 이 상태에서 손가락을 떼지 않고 확대/축소를 하기 위해 움직이면 UITouchPhaseMoved, 즉 touchesMoved 메시지가 수신되고 마지막으로 손가락을 떼면 UITouchPhaseEnded, 즉 touchesEnded 메시지가 수신됩니다.

각각의 이벤트는 1-touch와 n-touch 모두 동일하게 발생 되며, UIControl을 상속받아 구현된 UIButton이나 UISlider등의 컨트롤은 이미 이러한 터치 이벤트를 처리하고 있기 때문에 개발자가 기본적인 기능만을 이용한다면 위의 이벤트를 처리할 필요가 없습니다. 하지만, Safari나 Google map같이 페이지를 확대/축소 하거나 위/아래로 이동하기 위해서는 해당 view에서 터치 이벤트를 수신하여 처리하여야 합니다.

HAN
위와 같은 이벤트를 처리하기 위해서는 UIView 클래스를 상속받은 View 클래스를 생성하고 그 클래스 안에서 메시지를 받아서 처리하여야 합니다. 이러한 동작을 하는 프로젝트를 생성하는 방법은 다음과 같습니다.

1. "Xcode"를 실행한 뒤 새 프로젝트를 생성합니다.

2. 다음 그림과 같이 "New Project" 창에서 "Windows-Based Application"을 선택한 뒤 "Choose" 버튼을 누릅니다.

사용자 삽입 이미지


3. 이번엔 생성하고자 하는 프로젝트 이름을 입력합니다. 여기서는 "EventHandling" 이라는 이름으로 프로젝트를 생성하겠습니다.

사용자 삽입 이미지


4. 아래 그림은 "Windows-Based Application"으로 생성된 가장 기본적인 응용 프로그램의 모습입니다. 이 중 "MainWindow.xib" 파일은 View나 기타 화면에 관련된 리소스를 포함하고 있는 파일이며, 새로운 View 클래스를 생성하기 위해 이 파일을 더블클릭 하여 "Interface Builder"를 실행합니다.

사용자 삽입 이미지


5. 다음은 "Interface Builder"의 모습입니다. 새로운 View를 추가하기 위해 "Library" 도구 창의 "View"를 드래그 하여 "Window"창으로 드랍 합니다.

사용자 삽입 이미지


6. View 의 위치가 "Window"안에 꽉 차도록 적당히 레이아웃을 배치합니다.

사용자 삽입 이미지


7. 이번에는 새로 생성된 View에 label을 추가합니다. View와 마찬가지로 "Library" 도구 창의 "Label"을 드래그 하여 "Window" 창으로 드랍 합니다.

사용자 삽입 이미지


8. "Label"을 "Window" 창으로 드랍한 뒤의 모습입니다.

사용자 삽입 이미지


9. "Label"의 위치와 "Text"값을 통해 내용을 수정합니다. 또한 Baseline, Layout 등을 통해 정렬 상태를 변경할 수 있습니다.

사용자 삽입 이미지


10. 이번에는 실제 코드에 사용될 UIView 클래스를 상속받은 View를 생성하기 위해 View의 클래스 이름을 변경합니다. "Window"창의 View를 선택한 뒤 "MyUI View Identity" 도구 창(4번째 탭)의 "Class"에 생성하고자 하는 클래스 이름을 입력합니다. 여기서는 "MyUIView"를 입력하였습니다.

사용자 삽입 이미지


11. 이번에는 "Label"을 코드와 연결하기 위한 선언을 합니다. "MyUI View Identity" 도구 창(4번째 탭)에서 "Class Outlets"의 하단에 있는 "+" 버튼을 눌러 새로운 항목을 생성하고, 해당 항목의 "Outlet"을 지정합니다. 여기서는 "helloLabel"를 입력하였습니다. 또한 이 항목의 데이터 형을 "UILabel"로 지정하기 위해 오른쪽 "Type"에 "UILabel"이라고 입력합니다.

사용자 삽입 이미지


12. 여기까지 작업이 완료되었다면, label과 실제 UI 상의 객체와 매핑 하는 일이 남았습니다. "MyUI View Connections" 도구 창(2번째 탭)에서 "Outlets"에 있는 "helloLabel"의 오른쪽 원 가운데를 드래그 하여 "Window"창의 "Label" 객체에 드래그 합니다. 아래 그림과 같이 드래그 중에 매핑 될 객체의 정보가 간단히 툴팁으로 표시됩니다.

사용자 삽입 이미지


13. 모든 작업이 완료된 후의 모습입니다.

사용자 삽입 이미지


14. 지금까지 작업한 내용을 저장합니다.

사용자 삽입 이미지


15. 저장한 결과를 바탕으로 실제 클래스 파일을 생성하기 위해 "Window"창의 "View"를 선택한 후 메뉴의 "File"-"Write Class Files..."를 선택합니다.

사용자 삽입 이미지


16. 기본적으로 위에서 입력한 "MyUIView"가 표시됩니다. 만약 윗 단계에서 "View"를 선택하지 않으면 다른 클래스를 저장하는 창이 나옵니다.

사용자 삽입 이미지


17. 생성한 클래스를 현재 프로젝트에 추가할 것인지 선택합니다. 사용할 예정이기 때문에 체크한 뒤 "Add"를 눌러 추가합니다.

사용자 삽입 이미지


18. 모든 UI 작업이 끝났으므로 "Interface Builder"를 종료합니다.

사용자 삽입 이미지


19. 최종적으로 생성된 UI 코드 입니다.

사용자 삽입 이미지


위의 방법으로 생성된 코드를 이용하여 터치 이벤트를 핸들링 하는 예제를 작성하여 보겠습니다.

자동으로 생성된 클래스의 부모 클래스를 지정하기 위해 "MyUIView.h"에서 다음과 같이 주석처리 되어 있는 부분을 수정합니다. 또한, 이벤트 처리를 위한 함수를 추가합니다.

@interface MyUIView : /* Specify a superclass (eg: NSObject or NSView) */ {
IBOutlet UILabel *helloLabel;
}

@end


@interface MyUIView : UIView {
IBOutlet UILabel *helloLabel;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

@end


또한, 이벤트 핸들링을 수행하는 함수를 "MyUIView.m" 파일에 추가하고 각각의 함수를 채웁니다.

#import "MyUIView.h"

@implementation MyUIView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Began";
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Ended";
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Moved";
}

@end


위 코드에서는 각각의 이벤트가 발생하면 "helloLabel"의 Text를 바꿈으로써 알 수 있도록 하였습니다.
이제 코드를 컴파일 한 뒤 실행하면 터치/드래그 할 때마다 Label의 텍스트가 변경하는 것을 볼 수 있습니다.

여기에서 좀 더 확장하여 터치 후 드래그시 Label이 드래깅 되는 부분을 따라다니도록 수정 해보겠습니다. "touchesMoved" 함수를 수정하여 원하는 기능을 수행할 수 있습니다.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
helloLabel.text = @"Moved";

UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self];

CGRect labelPosition = [helloLabel frame];

labelPosition.origin.x = currentTouchPosition.x;
labelPosition.origin.y = currentTouchPosition.y;

[helloLabel setFrame:labelPosition];
}


위와 같이 수정한 뒤 iPhone 에뮬레이터를 실행하면 드래그 할 때마다 Label의 위치가 변경되는 것을 볼 수 있습니다.



사용자 삽입 이미지

아래는 본 실습에 사용된 코드 입니다.


Posted by AccessDenied

Leave your greetings.

iPhone/강좌2009/02/13 14:03
아이폰 어플리케이션 개발이 많은 이슈가 되고 있고, 개발자들의 관심이 날로 증가하고 있습니다. 저희 아이렌소프트도 현재 아이폰 어플리케이션 개발에 착수하였습니다. 이에 아이폰 어플리케이션에 대한 공부를 시작하고 있는데, 이를 내부적으로만 사용하기 보다는 여러 개발자분들과 함께 토론하며 같이 성장하자는 의미에서 앞으로 공부하며 나오는 산출물들을 공개하기로 하였습니다. 첫번째로 애들에서 제공하는 문서인 iPhone Application Programming Guide 를 이용하여 공부하는 내용을 챕터벌로 올릴 예정입니다. 그리고 중간중간 저희가 먼저 삽질했던 부분을 정리하여 팁 & 태크 형식으로 올릴 것 입니다. 또한 기획인 관점에서 인기있는 아이폰 어플리케이션의 리뷰를 진행할 것이며, 아이폰에 대한 새로운 소식을 접하게 되면 그것들을 소개드릴 것 입니다. 아무쪼록 많은 개발자와 기획자 분들도 동참하시어 서로 정보를 공유하며 함께 많은 발전 이루기를 진심으로 기원해봅니다. 아이폰의 한국 출시가 거의 확정되어 있는 상황에서 아이폰 커뮤니티로 발전해 나가길 바랍니다. 먼저 아이폰의 Core에 대해 소개해 드리겠습니다.
 
The Core Application


모든 아이폰 어플리케이션은 UIKit 프레임워크를 사용하여 만들어집니다. 그러므로 모든 아이폰 어플리케이션의 코어(Core)는 같은 구조를 가지고 있습니다. 이것은 대부분의 운영체제가 제공하는 방식이므로 크게 특별한 부분은 없습니다. 윈도우는 MFC나 Windows API를 제공한다는 것과 리눅스 또한 Linux API를 이용하여 프로그래밍 한다는 것과 같습니다.

Core Application Architecture

어플리케이션이 동작한 순간부터 끝날때까지 UIKit 프레임워크는 어플리케이션의 주요 구조의 대부분을 관리합니다. 아이폰 어플리케이션은 시스템으로 부터 계속 이벤트를 받아서 응답합니다. 이벤트를 받는것은 UIApplication 오브젝트의 역할입니다. 하지만 이벤트에 대한 응답은 사용자가 작성하는 코드에서 이루어집니다. 어디서 이벤트에 대한 응답을 할 것인지를 이해하기 위해서는 life cycle과 event cycle에 대한 이해가 필요합니다. 다음 챕터에서는 이 cycles와 아이폰 프로그램의 주요 디자인 패턴에 대해 설명합니다.



The Application Life Cycle

어플리케이션 life cycle은 시작과 종료 사이에 발생시키는 이벤트의 부분으로 구성됩니다. 어플리케이션이 시작 될 때 아이폰 어플리케이션도 main 함수로부터 시작되는데 이때 UIKit은 어클리케이션의 UI를 로드하고 이벤트를 받을 준비를 합니다. 프로그램이 동작하는 동안 UIKit은 이벤트를 사용자의 오브젝트에 전달하고 명령에 응답하는 역할을 수행합니다. 사용자가 프로그램을 종료시킬 때, UIKit은 어플리케이션에 종료 메시지를 전달하고, 프로세스의 종료를 시작하는 역할까지 수행하게 됩니다. 그림 1은 이러한 어플리케이션 라이프사이클을 도표화 한 것 입니다. 그림 1에서 보면 UIKit에서는 처음에 사용자의 탭으로 어플리케이션이 수행됩니다. 그때 appliationDidFinishLaunching를 통해 어플리케이션을 제어할 수 있습니다. 그 후 main()함수가 실행되고 UIApplicationMain 함수를 통해 이벤트를 받고 어플리케이션으로 전달하며, 어플리케이션은 Handle event를 통해 어플리케이션을 제어합니다. 어플리케이션이 정상적으로 동작하다가 사용자나 시스템이 어플리케이션 종료를 시도하면 applicationWillTerminate 메시지가 발생합니다. 사용자는 이 메시지를 받아서 종료시 처리해야 할 것을 수행 할 수 있습니다. 그 후 어플리케이션이 종료되는 것이 모든 아이폰 어플리케이션의 life cycle입니다.

사용자 삽입 이미지

그림 1. 어플리케이션 라이프 사이클


The Main Function

아아폰 어플리케이션에서 main 함수는 오직 굉장히 작은 일만을 수행합니다. 물론 아주 특별한 예외때 main 함수를 수정하여 사용할 수 있지만, 대부분의 어플리케이션의 main 함수는 코드 1과 같습니다.

#import <UIKit/UIKit.h>
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}

main 함수는 오직 세가지의 역할만을 수행합니다. 첫번째로 autorealese pool을 생성하고, UIApplicationMain함수를 호출합니다. 마지막으로 autorelease pool을 릴리즈하고 프로그램을 종료하게 됩니다.

Autorelease는 별도의 글을 통해 자세히 소개하기로 하고, 우선 UIApplicationMain 함수를 살펴보겠습니다. UIApplicationMain 함수는 네개의 인자(Parameters)를 받습니다.첫번째 두번째 인자인 argc, argv는 main 함수로 받는 것으로 쉘에서 프로그램을 실행 할 때 프로그램 실행 명령어와 함께 인자로 들어오는 값을 넣습니다. 그리고 세번째로 주요 클래스의 ID와, 네번째로 어플리케이션의 delegate 클래스를 넣습니다. 여기서 delegate 란 다른 클래스에 어플리케이션의 동작을 위임하기 위해 작성된 디자인 패턴으로, 프로토콜 규칙에 따라 구조를 맞추고, 필요한 메소드를 구현하면 그 클래스가 알아서 동작하게 되는 디자인 패턴을 말합니다. UIApplicationMain의 세번째 네번째 인자에  nil 을 넣으면 UIKit 은 UIApplication 클래스를 기본으로 사용하여, 네번째 인자에 nil을 넣으면 UIKit은 어플리케이션 delegate 가 nib 파일을 통해 로딩 될 것이라고 가정합니다.

The Application Delegate

사용자 레벨(High level)에서의 행동을 모니터링 하는 것은 개발자가 제공하는 delegate 오브젝트의 역할입니다. Delegation(위임) 방식은 UIKit 을 subclassing 하는 복잡함을 방지하는 매우 좋은 디자인 패턴입니다.


The Main Nib File

어플리케이션이 로딩될 때 수행하는 또다른 일 중 하나는 어플리케이션의 nib 파일을 로딩하는 것 입니다. 만약 어플리케이션의 Info.plist 파일이 NSMainNibFile key를 가지고 있다면 UIApplication은 nib 파일이 정의하는 것을 로드 합니다. main nib 파일은 자동으로 로드되는 한 하나의 nib 파일 입니다. 그러나 필요할 때 nib 파일을 사용자가 집접 로드할 수는 있습니다. Nib 파일은 디스크에 저장되는 하나 이상의 오브젝트의 스냅샷이 저장되어 있는 리소스(resource) 파일입니다. Main nib 파일은 일반적으로 window 오브젝트와 delegate 오브젝트가 포함되어 있습니다. 그리고 하나 이상의 윈도우를 제어 하기 위한 key 오브젝트로 구성되어 있습니다. nib 파일을 로딩하면 실제 메모리에 이 오브젝트를 재 구성하여 사용 가능한 상태로 만듭니다. 이것은 UIApplicatonMain에서 로딩하는 것과 동작 상 다른 점이 없습니다.


The Event-Handling Cycle

UIApplicationMain 함수가 초기화 된 후에, 어플리케이션의 이벤트 관리와 그림 그리기를 시작합니다. 이것은 그림 2에 묘사되어 있습니다.

사용자 삽입 이미지

그림 2. 이벤트와 그리기 주기

그림 2는 보면, 운영체제(Operating system)은 사용자의 터치를 감지하여 Event queue에 넣고, Event queu는 어플리케이션에 이벤트를 전달합니다. 어플리케이션 내부에서는 이벤트를 사용해야 하는 오브젝트에 이를 전달합니다. 동작이 완료되면 다시 운영체제로 결과를 돌려주고, 운영체제는 이를 화면에 표현합니다.
아이폰 어플리케이션에서는 멀티 터치 이벤트를 지원합니다. 하지만 멀티 터치가 여러개의 이벤트를 생성하는 것이 아닌, UIEvent라는 하나의 이벤트에 캡슐화 되어 들어가 있습니다. 터치에 관련된 이벤트는 UIEvent에 UITouch 오브젝트를  포함하여 전달하게 됩니다.

어플리케이션이 실행되면, 시스템은 어플리케이션을 위해 프로세스와 하나의 쓰레드를 생성합니다. 생성된 쓰레드는 어플리케이션의 메인 쓰레드가 되고, 이것은 UIApplicaton이 mian run loop 에서 동작합니다. 그림 3은 main run loop 와 이벤트 제어의 관계를 나타냅니다.

사용자 삽입 이미지

그림 3. Main run loop

UIApplication 오브젝트는 입력되는 터치 이벤트를 적당한 responder 오브젝트로 분기하여 mian run loop를 설정합니다. responder 오브젝트는 UIResponder 를 상속받아 만들어지며, UIApplication, UIWindow, UIView, 그리고 모든 UIView의 서브 클래스의 인스턴스를 포함합니다.

추가로, UIResponder 클래스는 responder chain 을 가지고 있습니다. 이것은 만들어지는 이벤트가 링크로 연결되어 전달되며, 첫번째 responder가 이벤트를 처리하지 못하면, 두번째 responder 에 전달되고, 이렇게 끝까지 전달되면서 처리하는 구조입니다.

Fundamental Design Patterns

디자인 패턴에 대한 부분은 별도의 팁 & 태크에서 소개해 드리도록 하겠습니다.


The Application Runtime Environment

Fase Launch, Short Use

아이폰은 동시에 하나의 어플리케이션만 실행할 수 있습니다. 이것은 어플리케이션을 실행하기 위해서는 항상 홈 스크린에서 어플리케이션 아이콘을 클릭하여 실행해야 한다는 것을 의미합니다. 아이폰 어플리케이션은 빠르게 실행되고 빠르게 종료되어야 합니다. 만약 5초 이내로 어플리케이션이 종료되지 않으면 시스템이 이것을 강제로 종료합니다.

아이폰 어플리케이션은 백그라운드에서 동작하지 않기 때문에, 종료시 최종 데이터를 저장해야 다시 실행 했을 때 마지막으로 동작하던 모습을 재현해 낼 수 있습니다.


The Application Sandbox

아이폰 어플리케이션은 보안상의 이유로 파일시스템의 지정된 곳에만 위치할수 있다. 이것은 sandbox라는 보안 기능의 부분 기능입니다. sandbox 라는것은 보안 분야에서 사용되는 언어로, 모든 실행과 데이터를 시스템이 알 수 있는 범위에서 동작하도록 하고 어플리케이션의 모든 행위를 모니터링 할 수 있게 하는 개념입니다. 이것을 위해 아이폰 어플리케이션은 다음의 위치에서만 실행 될 수 있습니다.

/ApplicationRoot/Application ID/


하지만 아무리 sandbox로 동작한다고 해도 어필리케이션의 오버플로우나 기타 해킹 방법으로부터 자유로울 수는 없다는 것을 명심 하시기 바랍니다.


The Virtual Memory System

어플리케이션 메모리를 관리하기 위해 아이폰 OS는 Mac OS와 같은 virtual memory 시스템을 사용합니다. 다만 아이폰에서는 메모리가 부족할 때 디스크에 메모리 페이지를 쓰는 swap 기능을 사용하지 않습니다. 이는 빠른 동작을 위한 조치라고 판단됩니다. 대신 아이폰 OS는 현재 메모리에서 사용하지 않는 메모리의 코드 영역 같은 부분을 내려서 공간을 확보하며, 그래도 메모리가 부족하면 동작하고 있는 어플리케이션에 현재 필요없는 메모리를 해지하라는 메시지를 보냅니다. 어플리케이션은 이 메시지에 응답하여 cache나 불필요한 메모리를 해지할 의무가 있습니다.


The Automatic Sleep Timer

아이폰 OS에서는 베터리를 절약하기 위한 방법으로 자동 sleep timer 를 사용합니다. 사용자가 일정 시간동안 아이폰을 터치하지 않아서 이벤트가 발생되지 않는다면 아이폰 OS에서는 자동으로 시스템을 정지시키고 스크린을 끕니다. 하지만 게임이나 동영상 플레이어 같은 어플리케이션은 사용자 입력 없이도 오랜 시간 동작해야 할 수 있기 때문에 UIApplication 오브젝트의 idleTimerDisabled 속성을 YES로 만들어서 자동 slee timer를 끌 수 있습니다.


The Application Bundle

아이폰 어플리케이션을 빌드할 때, XCode는 Bundle과 함께 패키지 합니다. Bundle은 하나의 그룹화 되어 있는 하나의 디렉토리 입니다. 번들은 아래 내용과 같이 어플리케이션 아이콘, 프로그램 실행 파일 등 여러가지로 구성됩니다.

   MyApp - 실행 파일.Settings.bundle - 프로그램의 속성과 다른 리소스 파일에 대한 내용을 포함

Icon.png - 57 x 57 사이즈의 홈 스크린에서 보여지는 어플리케이션 아이콘

Icon-Settings.png - 29 x 29 사이즈의 어플리케이션이 동작할 때 어플리케이션 이름 옆에 나오는 아이콘

MainWindow.nib - 어플리케이션의 main nib 파일입니다. 이것은 어플리케이션의 main 윈도우 오브젝트와 delegate object 를 포함하고 있습니다. 다른 interface 오브젝트는 추가적인 nib 파일로 부터 로드하거나 소스 레벨에서 포함합니다. Info.plist 파일의 NSMainNibFile key 를 변경하여 이 파일 이름을 변경할 수 있습니다.

Default.png - 480 x 320 사이즈의 이미지로, 어플리케이션이 시작할 때 보이는 이미지 압니다.

iTunesArtwork - 512 x 512 사이즈의 이미지로, 어플리케이션을 배포할 때 보여지는 이미지 입니다. 이것은 appstore에 배포될 때 보여지게 됩니다.

Info.plist - 어플리케이션의 bundle ID, 버전 그리고 보여지는 어플리케이션 이름 등 어플리케이션의 주요 속성이 들어있습니다.

sun.png - 해당 언어가 지원되지 않을 때 보여지는 이미지입니다.

en.lproj, fr.lproj, es.lproj ... - 지원 언어 리소스 입니다.


The Information Property List

Info.plist 파일은 모든 아이폰 어플리케이션이 포함하고 있는 속성 파일입니다. 이것은 XCode의 Active Target TargetName 메뉴를 클릭하여 GUI로 수정할 수 있습니다.(그림 4)

사용자 삽입 이미지

그림 4. Active Target

여기서는 기본적인 이름등을 수정할 수 있고, 더 자세한 설정은 하단에 있는 Open Info.plist as File을 클릭하면 그림 5와 같은 화면이 실행되고 여기서 모든 속성을 수정할 수 있습니다.

사용자 삽입 이미지

그림 5. Info.plist 파일

Handling Critical Application Tasks

이 장에서는 어플리케이션이 꼭 수행해야 할 역할을 기술합니다.


Initialization and Termination

어플리케이션이 초기화되고 종료되는 동안 UIApplication 클래스는 해당 메시지를 전송합니다. 어플리케이션은 delegation 오브젝트에서 이것을 처리해야 합니다. 초기화와 종료를 처리하는것은 필수 사항은 아니지만, 어플리케이션의 초기화때 데이터를 초기화 하거나 종료할 때 데이터를 저장하는 등의 역할을 수행하기 때문에 대부분의 어플리케이션에서는 이 메시지를 이용해야 할 것입니다. 아이폰 어플리케이션은 시작과 종료가 빠르고 가볍게 처리되야 하기 때문에 이 메시지를 적절히 이용해야 하는데, 만약 어플리케이션이 네트워크로부터 데이터를 받아오거나 복잡한 연산을 하여 초기화가 느릴 때, 먼저 UI를 보여주고 그 후에 초기화를 처리하는 방법 등으로 작업을 해야 합니다.

다음 글 박스에서는 UIApplicationDelegate에서 초기화와 종료시에 사용하는 메소드 프로토콜을 설명합니다.

applicationDidFinishLaunching - 어플리케이션이 시작 될 때 실행되는 메소드 입니다.

applicationWillTerminate - 데이터를 저장하거나 어플리케이션의 상태를 저장합니다. 어플리케이션 종료 시 호출됩니다.


Responding to Interruptions

사용자가 홈 버튼을 클릭하여 프로그램을 종료시키는 것 이외에도, 시스템이 어플리케이션에 interrupt를 걸어서 사용자의 입력을 기다릴 수 있습니다. 예를 들어 전화가 오거나 SMS가 오는 경우에 사용자에게 다음 수행을 물어보고 전화를 받는다면 어플리케이션은 종료되게 됩니다. 그림 6은 이러한 동작을 표현합니다.

사용자 삽입 이미지

6. Interrption

1. 시스템이 전화나 SMS가 전송되거나 달력에서 이벤트가 발생하는 것을 탐지합니다.

2. Deligate의 applicationWillResignAcive를 호출합니다.

3. 시스템이 alert 패널을 띄워서 사용자에게 전화나 SMS 수신 등의, 해당 이벤트를 알립니다.

4. 만약 사용자가 해당 이벤트를 무시하면 applicationDidBecomeActive 를 호출합니다.

5. 사용자가 해당 이벤트의 수행을 지시하면 applicationWillTerminate 를 호출합니다. 이때 어플리케이션은 종료시와 마찬가지로 데이터나 어플리케이션 속성을 저장해야 할 것입니다.

아이폰 OS가 sleep 모드로 들어가거나 다시 깨어날 때도 applicationWillResignAcive와  applicationDidBecomeActive가 호출됩니다.


Observing Low-Memory Warnings

시스템이 low-memory notification을 어플리케이션에 전달하면 어플리케이션은 빠르게 필요없는 메모리를 해지해야 합니다. 이 notification을 알 수 있는 방법은 3가지가 있습니다.

  • applicationDidReceiveMeoryWarning 을 delegate에 구현합니다.
  • UIViewController의 didReceiveMeoryWarning 을 override 합니다.
  • UIApplicationDidReceiveMemoryWarningNotification 메시지를 등록하여 처리합니다.
Customizing Your Application's Behavior

이 장에서는 사용자의 경험에 기반하여 어플리케이션을 최적화 하는 방법을 제시합니다.


Launching in Landscape Mode

아이폰 어플리케이션은 기본적으로 potrait mode(세로)로 동작한다. 만약 portrait mode와 landscape mode 둘다 지원한다면 portrait mode 로 시작하는 것이 좋다. 만약 landscape 모드로만 동작하게 하려면 다음의 과정을 거쳐야 한다.

  • Info.plist 파일에 UIInterfaceOrientation 키를 추가하고, 여기에 landscape mode 를 세팅한다UIInterfaceOrientationLandscapeLeft(홈 버튼이 왼쪽 기준)또는 UIInterfaceOrientationLandscapeRight (홈 버튼이 오른쪽 기준) 속성 중 하나로 선택하면 된다.
  • 어플리케이션 UI를 landscape 모드에 맞게 만든다.
  • shouldAutorotateToInterfaceOrientation 을 landscape 모드에서는 YES를 리턴하게 하고, POTRAIT 모드에서는 NO를 리턴하게 한다.

Communicating with Other Applications


만약 어플리케이션이 시스템에 등록된 종류의 URL을 호출하면 시스템은 해당 URL에 해당하는 어플리케이션을 동작시킨다. 예를 들어 Map을 보여주는 URL을 실행하면 등록된 Google map 이 실행되는 것이다. 이것을 통해 어플리케이션간 통신을 수행 할 수 있습니다. 애플에서는 http(사파리), mailto(애플 기본 메일 클라이언트), tel, sms의 URL 기능을 기본적으로 제공합니다. 이 기능을 사용하기 위해서는 NSURL 오브젝트를 생성하여 UIApplication 오브젝트의 openURL 메소드를 사용하면 됩니다. 이를 통해 다른 어플리케이션이 실행되면 기존의 어플리케이션이 잠시 종료되고, 새롭게 실행된 어플리케이션이 종료되면 다시 자동으로 실행되게 됩니다.

다음은 다른 어플레이케이션에 데이터를 전송하는 예제 코드입니다.


NSURL *myURL = [NSURL
URLWithString:@"todolist://www.acme.com?Quarterly%20Report#200806231300"];
[[UIApplication sharedApplication] openURL:myURL];


위 코드를 보면 todolist 로 시작하는 URL을 사용하는 것을 볼 수 있는데, 이것은 아이폰 OS에 등록된 어플리케이션이 실행되면서 뒤의 URL을 전달하게 되는 것 입니다.


Implementing Custom URL Schemes


애플에서 기본적으로 세팅한 URL type은 변경할 수 없지만, 그 외의 URL type은 개발자가 별도로 등록할 수 있다. 이것을 수행하기 위해서는 Info.plist 파일에 CFBundleURLTypes 속성을 통해 등록합니다. 다음 글 박스는 이 속성의 값을 설명합니다.

CFBundleURLName - URL Type의 이름입니다. 이것은 어플리케이션별로 unique 해야 하기 때문에 DNS 를 거꾸로 표현한것 과 같은 com.acme.myscheme과 같은 방식을 사용하기를 권장합니다.

CFBundleURLSchemes - URL의 앞부분에 들어가는 이름을 문자열로 입력하며, 여러개를 사용할 수 있습니다. 예를 들어 todolist, dolist 등과 같이 등록하면 이 형식의 URL이 로드되면 해당 어플리케이션이 동작합니다.


이 기능을 테스트 하기 위해서는 safari를 사용하면 됩니다.


Handling URL Requests


다른 어플리케이션이 URL request를 통해 해당 어플리케이션을 동작시켰다면 이것은 delegate의  APPLICATION:handleOpenURL 메소드를 구현하여 처리할 수 있습니다. 이 메소드를 통해 입력되는 NSURL을 처리하여 동작시키면 됩니다.


Displaying Application Preferences


사용자가 바꾸는 설정이 바로 적용되거나 무엇인가 동작이 바뀌기를 기대하는 것은 어플리케이션 내부에 넣고, 그렇지 않은 것은 시스템의 설정에 넣으면 됩니다. 시스템에 넣는것은 Settings.bundle에 포함시켜서 설정할 수 있으며 Icon-Settings.png를 Bundle에 넣으면 시스템 설정창에 해당 아이콘이 보여지게 되며, 제공하지 않으면 기본적으로 어플리케이션 아이콘이 등록됩니다.


Internationalizing Your Application


텍스트, 이미지 등 모든 리소스는 사용하는 아이폰의 언어에 따라 다르게 보여지게 할 수 있습니다. 시스템에서 기본적으로 제공되는 alert나 기타 컨트롤들은 기본적으로 이 기능을 가지고 있습니다. 일반 어플리케이션에서 이 기능을 사용하려면 pInfo.list 에서 설정하여 사용할 수 있습니다. pInfo.list에서 lproj 폴더를 지정하여 해당 폴더에 코드가 생성하는 텍스트, 기본 텍스트, 아이콘, 사운드 파일, Nib 파일등을 넣을 수 있습니다.

lproj의 서브 디렉토리는 다음과 같습니다.

en.lproj/
- InfoPlist.strings / - 이 디렉토리에는 각 국가별 언어 디렉토리를 하위 디렉토리로 가지고 있습니다. 예를 들어 프랑스 언어는 fr.lproj 디렉토리를 통해 지원할 수 있습니다.
- Localizable.strings / - 어플리케이션이 생성하는 스트링이 포함됩니다.
- sign.png / - 국가별로 구분되는 이미지


NSLocalizedString 매크로를 이용하여 코드상에서 언어를 구분하여 지원할 수 있습니다.


NSString *NSLocalizedString(NSString *key, NSString *comment);

label.text = NSLocalizedString(@"City", @"Label for City text field");


NSLocalizedString은 key와 comment로 구성되어 있습니다. key는 언어를 말하며, 이것을 번역하기 위해 필요한 커맨드를 넣을 수 있습니다. 그 후 lproj 폴더에 다음과 같은 키를 Localizable.strings 파일에 넣으면 해당 언어로 번역됩니다.

"City" = "Ville";

다국어 지원에 대한 것은 더 자세히 팁 & 태크에서 소개해 드리겠습니다.

Tuning for Performance and Responsiveness


Using Memory Efficiently


메모리를 효과적으로 사용하기 위해서는 다음과 같은 사항을 지키시기를 권장합니다.
  • 메모리 릭을 최소화 해라
  • 리소스 파일을 최대한 작게 사용해라
  • 큰 데이터는 SQLite 를 이용하여 저장하고 불러와라.
  • 리소스는 필요할때만 불러와라.
  • Thumb 를 이용하여 컴파일하면 35%의 메모리가 절감된다. 하지만 그만큼 퍼포먼스는 떨어진다.

Allocating Memory Wisely

메모리를 할당할 때는 다음과 같은 사항을 지키시기를 권장합니다.
  • Autorelease 사용을 최대한 줄이고, 개발자가 직접 allocating 하고 release 해라.
  • 리소스를 줄여라.
  • 문제가 되는 메모리 사용을 회피해라.


Reducing Power Consumption


다음 기능의 사용의 최소화 하여야 베터리를 오래 쓸 수 있습니다.
  • Wi-fi radio
  • baseband cell radios
  • Core location framework (GPS)
  • Accelerometers (가속도 센서)
  • Disk
이로서 첫번째 챕터의 소개가 끝났습니다. 지금은 문서를 번역하고, 그에 따른 약간의 양념을 가미한 수준입니다. 하지만 앞으로 팁&태크나 새로운 강좌들을 통해 더욱 많은 소개 드리도록 하겠습니다. 아직까지 애플에서 제공되는 문서를 통해 포스팅을 하는 것은, 원문과 다르게 더 좋은 글을 쓰려고 하는것은 거의 불가능 하므로, 원문에 충실하게 계속 포스팅 하겠습니다.
Posted by Getroot

Leave your greetings.

  1. 정말 최고의 강좌네요. 원리를 알고 아이폰을 접근할 수 있어서 감사합니다. ^^

    2010/03/22 15:55 [ Permalink : Modify/Delete : Reply ]
  2. bellMT.

    좋은정보네요!~ 감사드립니다.

    2010/08/04 11:33 [ Permalink : Modify/Delete : Reply ]
  3. thanks for your posting

    2010/10/01 16:42 [ Permalink : Modify/Delete : Reply ]
  4. pkseop

    멋집니다. 정리하느라 수고 많이 하셨을듯 하네요.

    2010/12/06 20:13 [ Permalink : Modify/Delete : Reply ]

ShowSpace2009/02/11 16:35
쇼스페이스는 서비스형 플래시 갤러리 입니다. 서비스형 플래시 갤러리는 설치형 플래시 갤러리와는 다르게 별도의 프로그램을 설치하여 플래시를 만드는 작업이 필요없습니다. 단지 단순히 사진을 업로드 하는 것 만으로 자동으로 갤러리를 만들어줍니다. 보기 방식을 바꾸는 작업이나, 기타 여러가지 설정도 웹에서 클릭 한번으로 바로 할 수 있습니다.

설치형 플래시는 플래시 갤러리 프로그램을 설치 한 후에 여러가지 기반 지식을 쌓고, 복잡한 작업 과정을 거쳐야만 플래시 갤러리 파일인 SWF 파일을 만들어줍니다. 그것을 블로그나 게시판에 올리기 위해서는 저작툴이 만들어준 SWF 파일을 일일히 업로드 해야 합니다. 행여나 어떤 사이트에서 SWF 파일 업로드를 막았다면 만든 플래시 갤러리는 쓸수가 없게 되지요. 또 다른 사람들이 퍼갈수도 없습니다. 하지만 설치형 갤러리는 사용자가 어느정도 지식이 있다면 정말 세세한 부분까지 수정할 수 있다는 장점이 있습니다. 그래서 파워 유저나 프로그래머가 선호하며 사용하고 있습니다.

최근 다양한 설치형 플래시 갤러리가 많이 나오고 있고, 또 어떤 갤러리는 꽤 많은 인기를 끌고 있습니다. 쇼스페이스 기획을 위해 간단히 조사를 해보니 대표적으로 다음과 같은 프로그램들이 있었습니다.

1. Autoviewer
오른쪽과 왼쪽 끝에 있는 버튼으로 사진을 한장 한장 넘겨서 볼 수 있으며, 자동 플레이 기능을 제공합니다. 사진 확대/축소가 지원되지 않습니다.

http://www.airtightinteractive.com/projects/autoviewer/


2. Polaroid gallery
폴라로이드 사진을 바닥에 뿌려놓은 것과 같은 효과를 줍니다. 사진을 옮길 수 있고, 더블 클릭하면 확대되어 보여집니다.

http://www.loved.pe.kr/blog/wp-content/uploads/2009/02/polaroidgallery-100x120.png


3. Postcard viewer
사진을 엽서와 같은 모양으로 바꿔서, 벽에 붙여놓은것 같은 효과를 줍니다.

http://www.airtightinteractive.com/projects/postcardviewer/ 


쇼스페이스는 서비스형 플래시 갤러리이지만, 설치형의 유연성을 도입하여, 다양한 보기 방식과 여러가지 설정을 할 수 있는 기능을 제공 하고 있습니다. 위에 나온 2번 3번과 같이 출력되는 보기 방식 추가가 곧 있을 예정이니 기대해 주시기 바랍니다.

항상 발전하는 쇼스페이스가 되겠습니다.
Posted by Getroot

Leave your greetings.

  1. 와우!

    잠깐 안 들린 사이에 엄청나게 많은 기능들이 첨가(?)되었네요!
    내일 또 써 보겠습니다, 멋집니다!

    2009/02/11 22:01 [ Permalink : Modify/Delete : Reply ]
    • Getroot

      앗... 다른 설치형 플래시 갤러리들을 소개시켜드린것인데, 쇼스페이스에 들어간것으로 잘못 보셨나봐요 ^^; 2번과 3번과 같은 보기 방식은 추가 계획에 있습니다.

      2009/02/12 09:46 [ Permalink : Modify/Delete ]
    • 흑, 망신스럽게 포스트를 대충 본 티가 나네요.
      늘 화이팅입니닷!

      2009/02/13 13:07 [ Permalink : Modify/Delete ]
  2. 냥냥이

    2번 폴라로이드 겔러리 사진이 보이질 않네여~ >< 항상 응원합니다!

    2009/02/13 22:38 [ Permalink : Modify/Delete : Reply ]

ShowSpace2009/02/04 20:20

쇼스페이스는 진정한 개인 사진첩입니다.

쇼스페이스는 처음부터 자신만이 볼 수 있는 개인 사진첩으로 기획하였습니다. 그래서 사용자가 직접 사진첩을 올리지 않으면 공유가 되지 않도록, 별도의 공개나 검색 기능을 넣지 않았습니다. SNS, 블로그, 카페, 클럽 등 너무 많은 정보 공유 사이트들 속에서, 정작 나만의 사진첩, 나만의 노트는 없는 것아닌가 생각해 보았습니다. 우리들은 항상 길거리에 있는 칠판에 글을 쓰고 사진을 붙여오지는 않았나 생각해보았습니다.

여러 공유 서비스를 이용하면 자신이 원하던 원하지 않던, 전혀 모르는 엉뚱한 사람이 나의 개인적인 사진들을 보게 됩니다. 그로 인해 많은 피해가 발생하고 있습니다. 쇼스페이스를 이용하면, 정말 나만 사용하는 사진첩을 갖게 됩니다. 혹자들은 저희에게 "그런걸 원하는 사용자는 소수다. 다수는 공유를 원한다."라고 합니다. 예 맞습니다. 현재 시장 상황이 그걸 적나라하게 말해주고 있기 때문에 저희도 몸으로 느끼고 있습니다. 하지만 소수를 위한 서비스가 하나쯤은 있어야 하는것 아닌가 하는 생각 해봅니다. 소수의 기쁨도 저희에게는 똑같은 기쁨이기 때문입니다.

쇼스페이스로 사진의 저작권을 보호할 수 있습니다.

내가 만든 사진 플레이어에 들어간 사진들은, 플레이어를 통해서는 원본 그대로 다시 저장할 수 없습니다. 물론 화면 캡춰나 심지어 디지털 카메라로 모니터를 직접 찍는 행위등은 막을수가 없지만, 사진이 확대 되거나 주위 다른 사진들로 가려지기 때문에 캡춰나 사진을 찍어도 원본을 그대로 빼내갈 수는 없습니다. 단지, 플레이어 그대로 퍼갈 수만 있습니다. 플레이어를 퍼가면 어디서 퍼갔는지 통계 기능을 통해 모두 보이기 때문에, 사진 플레이어의 저작권을 보호할수가 있습니다.

원하는 사람에게만 사진을 보여줄 수 있습니다.

다른 서비스를 이용하면 원하는 사람에게만 사진을 보여줄수가 없습니다. 일촌에게만 보여주는 기능은 해당 서비스를 이용하지 않는 친구에게는 보여줄 수 없고, 또 일촌중 보여주기 싫은 사람만 안보여줄수도 없습니다. 블로그나 다른 여러 서비스도 마찬가지 입니다. 그럴때는 미니홈피나 블로그에 비밀 번호가 설정된 쇼스페이스를 올려보십시오. 비밀 번호를 입력해야만 사진이 보이는 비밀 사진첩 기능을 이용하면, 원하는 사람에게만 사진을 보여줄 수 있습니다. 나와 내 친구들만 아는 힌트를 이용해 비밀 번호를 만든다면, 또다른 재미가 있을것입니다.




Posted by Getroot

Leave your greetings.

  1. 냥냥이

    쉽게 퍼갈 수 있으면서 더불어 보호까지 된다면 이거 마음놓고 사진을 올릴 수 있겠는 걸요 ㅎㅎ

    2009/02/13 22:57 [ Permalink : Modify/Delete : Reply ]