순정이든 , 반탈한 기종이던 간에 원클릭으로 완벽하게 탈옥 시켜주는 방법을 소개합니다. 

  아무리 아이패드라 해도 오래 사용하다 보면 결국 리붓을 해 줘야만 하는 시점이 다가 옵니다. 그럴때
  반탈이면 여러모로 귀찮아 지지요. 그러던 와중에 드디어 원클릭으로 탈옥을 시켜주는 툴이 릴리즈가
  됐습니다. (사실 조금 됐습니다. 제가 요즘 바쁜 관계로..)


     일단 그린포이즌을 자기가 사용하는 OS 종류에 맞게 다운 받습니다. (저는 Mac 으로 다운 받았습니다) 다운
     받고 압축을 풀고 나온 실행 파일을 실행합니다. 




  2. "JailBreak" 버튼을 클릭합니다. 
     클릭 전에 잘 읽어보시면 클릭하고 나서는 DFU 모드에 진입 시키는 것을 알 수 있습니다. 



  3. 화면에 나온대로 실행해 줍니다. 

     슬립버튼 (Sleep) 은 아이폰/아이패드 오른쪽 상단 모서리에 있는 잠자기 버튼이고, 홈버튼 (Home) 은
     아래쪽 가운데 중앙에 있는 버튼 입니다. 

     슬립 버튼을 누르고 있는 채로 , 홈 버튼을 같이 누르고 있다가 , 슬립 버튼을 풀어주지만 여전히 홈
     버튼을 누르고 있는 것입니다. 

     DFU 모드 진입시키는 것이지요. 


  4. DFU 모드에 진입하면 자기가 알아서 탈옥 됩니다. (끝)


 역시 한방에 탈옥이 되는 데다가 완탈이 되니 허망하기 까지 합니다. 마구 마구 리부팅 해줍시다. 




UITextView 에서 단어 개별에 관한 특정 작업(색을 다르게 입힌다던가, 애니메이션, 이미지 추가)을 위해서는 단어가 출력되는 좌표와 크기를 알아야 합니다. 그 개별 개별 단어의 크기와 좌표를 알아내는 방법에 관한 글 입니다. 

iPhone apps 개발하는 중에 문장이 쓰여져 있는 UITextView 에서 특정 단어에 효과를 주고 싶었습니다. UIWebView 를 이용해서 화면에 글을 출력하고 CSS 와 Javascript 를 이용해서 개발하면 된다는 소리가 있기는 하던데, 제가 잘 아는 분야와는 조금 거리가 있어서, UITextView 를 수정하기로 했습니다. 

원리

원리는 쉽습니다. UITextView 에서 문장을 출력하는 경우라고 하면

1. 문장을 각 단어별로 쪼개서 NSArray 로 저장합니다. 

2. 쪼개진 단어가 표시되는 좌표와 테두리 크기를 알아냅니다. 

3. 변경을 주고 싶은 단어 위에 같은 크기(단어 와)의 UILabel 을 살짝 얹어줍니다. 

4. UILabel 에 이미지나 폰트, 글자색을 변경해 줍니다. 



즉 이렇게 보이는 화면이 있으면 , 아래쪽에 보이는 'Hello' 라는 버튼을 터치하면 



이런식으로 각 단어들이 보이는 듯이 색이 입혀집니다. 

구현

원리는 쉽지만, 막상 구현할려고 하니 힘들더군요. 비슷한 코드가 있나 찾아보는데만 반나절 이상을 소비했습니다. (결국 못찾아서 직접 만들어 줬습니다) 화면에 문장이 출력되는 부분에서 패딩을 생각 못해줘서 또 시간 많이 소비했구요. 

Object-C 와 아이폰 개발에 익숙치 않아서 , 문법이 이상한 것들이 조금 보이더라도 고수분들께서는 이해해주시기 바랍니다. (지적도 감사합니다 )


- (IBAction) rePaintWord: (id) sender 
{
    // color Array 를 만든다. 
    NSArray * color_array = [NSArray arrayWithObjects:[UIColor grayColor] , [UIColor redColor] , 
                                     [UIColor greenColor], [UIColor blueColor], [UIColor yellowColor],
                                     [UIColor orangeColor], [UIColor brownColor], nil];
    

    // 단어들 tokenizing 한다
    NSArray * myWords = [overLookTextView.text componentsSeparatedByString:@" "]; // 문장에 쓰인
    NSInteger count = [myWords count] ;

    // 실제로  contents 가 뿌려지는 textview 크기 보정을 한다. padding 크기를 
    // 보정 안해주면 반나절 이상 테스트 한다고 해도 제대로 결과가 나오지 않는다. 
   
    // padding size 이 패딩 사이즈는 일명 마법숫자(magic number)이다.
    // 원리도 모르고 어딘가에서 표시도 되지 않았다. -ㅅ- 
    int padding_size = 11; 

    CGSize content_size = CGSizeMake (overLookTextView.contentSize.width - padding_size ,
                                      overLookTextView.contentSize.height - padding_size);

    // 높이가 변하게 되는 단어를 지정하기 위한 산물이다. 즉 갑자기 높이가 변하는 단어는 lineBreak
    // 됐다고 보면 된다. 바로 그 시점의 높이와 Range 를 저장하기 위해서 이다. 

    CGSize last_string_size = CGSizeMake(0,0);
    NSRange last_result_range = NSMakeRange(0, 0);

    NSRange result_range = NSMakeRange(0, overLookTextView.text.length);

    for(int i = 0 ; i < count ; i++)
    {

        // 전체 문장에서 정확히 원하는 단어를 검색하기 위해서 이다. 정규표현식을 썼으며 
        // 단어 인 것들만 찾기 위해서 썼다. NSRegularExpressionSearch 는 
        // iOS 4.0 이상부터 지원한다고 한다. 
        result_range = [overLookTextView.text 
                         rangeOfString:[NSString stringWithFormat:@"\\b%@",
                          [myWords objectAtIndex:i]]
                         options:NSRegularExpressionSearch range:result_range] ;
       

        // 실제로 찾고자 하는 단어가 차지하는 영역 크기 
        CGSize wordSize = [[myWords objectAtIndex:i] 
                        sizeWithFont:overLookTextView.font forWidth:content_size.width 
                        lineBreakMode:UILineBreakModeWordWrap];


        // 시작부터 단어를 포함한 줄까지 잘라내기 
        NSString* head = [overLookTextView.text 
                  substringToIndex:result_range.location + result_range.length];

        // 위에서 잘라낸 단어줄의  content 크기 알아내기 , 이는 높이를 비교하기 위해서
        //  알아보는 것이다. 지난번 결과로 저장된 높이랑 틀려진다면
        // 줄이 바꼈음을 알고 바로 그 시점이 마지막 범위와 높이가 저장되는 시점이다. 
        CGSize string_size = [head sizeWithFont:overLookTextView.font 
               constrainedToSize:content_size lineBreakMode:UILineBreakModeWordWrap];
        if (string_size.height != last_string_size.height)
        {
            last_result_range = result_range ; // 줄바뀌는 첫번째 단어 의 시작 위치를 저장
            last_string_size = string_size ;
        }


        // head 는 문장의 처음부터 단어를 포함하고 있는 문자열까지 잘라낸 것이다. 
        // tail 은 줄이 바뀐 첫 단어부터 단어를 포함하는 곳까지 잘라낸 것이다. 
        NSString * tail = [head substringFromIndex:last_result_range.location];

        // lineSize 는 줄이 바뀐곳부터 단어를 포함한 곳까지의 크기를 얻어내서 저장하는 곳이다. 
        CGSize lineSize = [tail sizeWithFont:overLookTextView.font forWidth:content_size.width 
                                                    lineBreakMode:UILineBreakModeWordWrap];

        // temp_rect 는 단어가 위치하는 좌표값과 크기가 저장된다. 하지만 이는 
        // 실제로 위치한 곳과 확실하게 일치시켜 줄려면
        // textView 가 위치한 실제 좌표 값과 글자가 실제로 출력되는 
        // 위치까지의 'padding' 값을 더해 주어야 한다. 
        // 심각한 문제는 여기서 더해주는 padding 은 위에서 content 
        // 윈도 크기를 보정하기 위해서 더해주는 padding_size 값과는
        // 다르다는 것이다. 

        CGRect temp_rect = CGRectMake (lineSize.width - wordSize.width , 
                         last_string_size.height - wordSize.height ,
                                       wordSize.width , wordSize.height);


        // Test 삼아서 위치보정해주고 (textview , padding) 실제 글자 위치에 
        // 작은 Label 을 한개 만들어서 덮어놓는 함수를 작성했다.
        [self make_label_on_screen:[myWords objectAtIndex:i] 
              rect:temp_rect color:[color_array objectAtIndex:( i % [color_array count]) ]];

        // 검색 범위를 변경해 주는 곳이다. 단어를 찾은 크기만큼 이동해 주는 모듈
        int new_location = result_range.location + result_range.length ;
        result_range = NSMakeRange(new_location , overLookTextView.text.length - new_location);
    }
        
}

- (void) make_label_on_screen:(NSString *) word rect:(CGRect) 
                                        label_rect color:(UIColor *) color
{

    // 실제 위치를 표기해 주는 패딩과 textview 위치 찾기
    CGFloat ui_padding_size = 7.9;

    label_rect.origin.x += overLookTextView.frame.origin.x ; 
    label_rect.origin.y += overLookTextView.frame.origin.y ; 

    label_rect.origin.x += ui_padding_size;
    label_rect.origin.y += ui_padding_size;



    UILabel * nameLabel = [[UILabel alloc] initWithFrame:label_rect];
    nameLabel.text = word ;
    nameLabel.textColor = color;
    nameLabel.backgroundColor = [UIColor clearColor];
    nameLabel.textAlignment = UITextAlignmentRight;
    nameLabel.font = overLookTextView.font ;
    
    [self.view addSubview: nameLabel];
    [nameLabel release];
}
'Hello' 버튼에 대응되는 함수와 UILabel 을 한개 얹어주는 함수 두개를 만들어 줬습니다. 혹시 몰라서 Test 로 만들어본 프로젝트를 첨부 합니다. 




Edited: 2011 - 02 - 07 

  드디어 완탈이 가능해 졌습니다. 검색으로 여기까지 찾아오셨으면 완탈하는 포스트로 이동하시기 바랍니다. 
  


드디어 Cydia 문제까지 고친 버젼의 Redsn0w 0.9.6b4 가 나왔군요. 이걸 이용해서 한방에 (사실은 두방) 탈옥이 가능합니다.  

*주의* 
완전한 탈옥이 아닌 것을 유념하시기 바랍니다. 리부팅을 하거나 전원이 다 나가서 꺼지는 경우에는 꼭 Redsn0w 로 다시 부팅 시켜줘야 할 것입니다. 


먼저 필요한 파일들을 다운로드 받습니다. 

1. 먼저 iOS 4.2.1 다운 받습니다. 


예전에 발견해서 너무 잘 사용하고 있는 곳입니다. 

2. Redsn0w 0.9.6b4 를 다운 받습니다. 


3. iOS 4.2.1 로 아이패드를 업데이트/복원 해 줍니다. 

1번에서 받은 펌웨어를 iTunes 를 이용해서 '업데이트/복원' 해 줍니다. 


Mac 에서는 '옵션' 키를 누른채로 왼쪽 클릭하면 펌웨어 고르는 부분에서 1번에서 받아둔 펌웨어를 고르면 됩니다. 그리고 혹시 모르니 꼭 기존에 설치된 내용들을 꼭 '동기화' 를 시켜두는 것이 실패 확률을 줄여줄 것입니다. 

4. Redsn0w 0.9.6b4 를 실행합니다. 


하단에 보이는 'Browse' 버튼을 클릭해서 1번에서 받아둔 펌웨어를 선택해 줍니다. 



iPad1,1_4.2.1 을 확인하시고 


4.1 옵션 설치하는 화면 

싸이디아(Cydia) 를 설치하는 체크를 선택해 주면 됩니다. 그리고 'Next' 를 클릭하시면 됩니다. 


전원이 완전히 꺼진 상태에서 'Next' 를 클릭하라는 소리입니다. 클릭하면 DFU 모드로 진입 시키라는 명령이 나옵니다. (시키는 대로 따라서 하면 됩니다)

DFU 모드란?
iPad 상단 오른쪽에 있는 'Sleep/Wake' 을 몇초간 누르고 그 버튼을 누른채로 'Home' 버튼을 같이 8초 가까이 눌러주다가 상단 'Sleep/Wak' 버튼만 떼주고 'Home' 버튼을 누른채로 유지해주면 들어가는 모드 가 DFU 모드 입니다. 





그러면 자기가 알아서 쭈욱 진행합니다. 


그리고 완성되면서 탈옥(Jailbreak)이 완성됩니다. 그리고 서둘러서 아이패드를 보면 'Cydia' 어플이 설치 되어 있는 것이 확인 됩니다. 조금 이상해 보이긴 할 것입니다. 아이콘이 그냥 하얀색으로 보이거든요. 잽싸게 실행해 봅니다. 그러면 아마 십중팔구 (거의 99.9%)는 

Cydia 가 실행이 안될 것입니다!!!

4 번 과정부터 다시 실행해 줍니다. 4.1 인 옵션 고르는 화면에서 다음과 같이 골라줍니다. 


그리고 전원을 끄고 , 다음을 누르고 , DFU 모드 진입하는 과정을 그대로 따라서 해주면 됩니다. 그러면 싸이디아(Cydia) 앱스 의 아이콘이 제대로 들어옵니다. 그리고 당연하게도 실행도 잘 되고요. 


Jailbreak 후 가장 간단하게 해줄 일

게임 설치!!! 

가 아니고 AppSync 를 설치 해줘야 하지요. 

1. Cydia 실행 

2. 아래쪽 탭에 있는 'Manage' -> 가운데에 있는 'Sources' -> 상단 오른쪽에 있는 'Edit' 클릭 ->  상단 왼쪽에 있는 'Add' 클릭 

3. http://cydia.hackulo.us 입력하시고 'Add Source' 버튼 클릭

4. 'Add Anyway' 버튼 클릭 후 안정적으로 추가되면  하단 탭의 'Search' 를 클릭하고 "AppSync for OS 4.2' 을 설치합니다. 

널리 널리 퍼져서 내 아이패드 리퍼 안해준 저주를 받을 지여다!!!!









iPhone 에서는 실행파일 과 번들이 속한 디렉토리가 Read-only 기 때문에 읽고-쓸 수 있는 Sqlite 파일을 만들어 줄려면 수동으로 복사해 줘야 하는 코드가 필요합니다. 
즉 앱스가 읽고 쓸 수 있는 'Documents' 디렉토리에 번들로 포함된 Sqlite 파일을 옮겨주기만 하면 되는 것입니다. 

해결방법
- (void) createEditableCopyOfDatabaseIfNeeded {

    // test for existance

    NSFileManager * fileManager = [NSFileManager defaultManager];
    NSString *documentsDirectory = [self applicationDocumentsDirectory];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"OhReading.sqlite"];

    BOOL dbexists = [fileManager fileExistsAtPath:writableDBPath];

    if(!dbexists)
    {
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"OhReading.sqlite"];

        NSError * error;

        BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];

        if (!success) {

            NSAssert1(0, @"Failed to create writable database file with message '%@', ", [error localizedDescription]);
        }
    }

}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
    if (persistentStoreCoordinator_ != nil) {
        return persistentStoreCoordinator_;
    }
    
    NSURL *storeURL = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"OhReading.sqlite"]];
    NSError *error = nil;

    	[self createEditableCopyOfDatabaseIfNeeded];

    persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {





중간에 
[self createEditableCopyOfDatabaseIfNeeded]; 
라는 식으로 persistentStoreCoordinator 함수 중간에 추가해 주면 번들에 있는 OhReading.sqlite 파일을 읽고-쓸 수 있는 Documents 디렉토리에 복사해줍니다. 

매우 쉽게 해결하기는 했지만, 막상 저는 고생했습니다. 예전에 참조했던 책인 'Head First iPhone Development - 2009' 에서 해결하는 방법이 몸에 익어버렸기 때문입니다. (Chapter 07 , 359 page)


iOS (3.1.3) 해결 방법 (책에 나온 방법)

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    // Override point for customization after app launch    
	[self createEditableCopyOfDatabaseIfNeeded];
}

- (void) createEditableCopyOfDatabaseIfNeeded {

    // test for existance

    NSFileManager * fileManager = [NSFileManager defaultManager];
    NSString *documentsDirectory = [self applicationDocumentsDirectory];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"OhReading.sqlite"];

    BOOL dbexists = [fileManager fileExistsAtPath:writableDBPath];

    if(!dbexists)
    {
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"OhReading.sqlite"];

        NSError * error;

        BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];

        if (!success) {

            NSAssert1(0, @"Failed to create writable database file with message '%@', ", [error localizedDescription]);
        }
    }

}




하지만 이제 안되는 이유는 

applicationDidFinishLaunching  함수가 사라졌(?)습니다. 사실 존재하는 것 같기는 하지만 숨긴 것 같습니다. 대신 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  

함수가 대신해서 생긴 것 같습니다. 하는 일이 비슷한 것 같다는 것이죠. 
그렇다고 이렇게 만들면 문제가 발생합니다. 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
    // Override point for customization after application launch.

    [self createEditableCopyOfDatabaseIfNeeded];

    // Add the navigation controller's view to the window and display.
    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];

    return YES;
}



createEditableCopyOfDatabaseIfNeeded 

함수가 호출 되기 전에 이미 Documents 디렉토리에 sqlite 파일이 생기는 문제인데요. 대체 이유가 뭔가 해서 스택에 호출된 함수를 일일이 뒤지다가 시간이 다 지나갔습니다. 결국 '오컴의 면도날(클릭)' 을 생각해 냈습니다. '스택을 다 뒤지는 것 같이 복잡한 것이 아닐 것이다. 쉬운 해결 방법이 있을 것이다' 그래서 다른 접근 방법을 통해서
persistentStoreCoordinator 가 호출되기 전에 sqlite 파일이 존재하는지 체크해서 존재 안하면 생성 시켜버렸습니다. 






개발자로 살아 오면서 이거 저거 만지작 거리다 보니, 모바일 플랫폼쪽 개발을 자주 해보게 됐습니다. 윈도즈 모바일(Windows Mobile), 아이폰( iPhone)  , 안드로이드(Android) 로 이거 저거 만들어 봤습니다. 본의 아니게 자주 접하다 보니 이거 저거 장단점을 비교하게 되더군요.

나름 세개를 비교하는 오만을 저질를려고 하니 자신의 생각과 다르다고 하더라도 '이 사람은 이렇게 생각하는 구나' 하고 봐 주세요.

결론부터 이야기 하자면 개발자의 입장에서 가장 좋은 것은 안드로이드 라고 봅니다.

개인 개발자 측면에서 2가지만 이야기 하겠습니다. 추후에 상업화해서 돈을 얼마나 벌 수 있는 가에 대해서는 언급하기가 힘듭니다. 저 역시 그런 것으로 돈을 벌어본 적이 없어서요.

저는 그래서 개발자 측면에서 중요한 점을 돈과 개발 효율성 에 두고 있습니다.

첫째 돈에 관해서 입니다. 안드로이드는 개발하는 데 추가로 드는 비용이 전혀 없습니다.

Windows Mobile 개발할려면 돈이 듭니다. 다른건 모르겠지만 개발툴이 무지하게 비쌉니다. 모바일 개발 기능까지 포함한 Visual Studio 살려고 들면 몇백만원 이상으로 돈이 들 것입니다.

아이폰의 개발툴인 XCode 는 무료 입니다. 애플에 개발자 등록을 하면 바로 다운 받을 수 있습니다. 다만 개발을 하기 위한 OSX 가 깔려 있는 컴퓨터를 사야 합니다. 맥북 싼거부터 비싼 맥까지 가격은 천차 만별이지만, 맥 컴퓨터의 특성상 비쌉니다. 그리고 저 사양에서 개발은 쉽지가 않은 편이고요. 또한 맥북이 있다 하더라도 아이폰에 프로그램을 설치 하려면 '인증서'가 있어야 합니다. 개인 자격이니 1년에 10만원씩 인증서를 갱신하는 비용을 제공을 해야 아이폰에 자신이 개발한 프로그램을 설치 할 수가 있습니다.

"얘는 확실히 무료 입니다"



안드로이드는 사용하고 있던 피씨에 멀티 부팅으로 '우분투(Ubuntu)' 를 설치해주고, 이클립스(Eclipse) 를 설치하고, 안드로이드 SDK 를 설치해주면 개발 세팅 완료 입니다. 더구나 피씨 말고 전부 무료 입니다. 보통 피씨 없는 개발자는 없겠죠? 따라서 추가로 들어가는 돈은 전무 합니다. 개발을 잘 하기 위해서 새로 시스템을 갖추지 않는 경우에는 말이죠.

"개발 툴의 끝판 왕이라 불리는 이클립스"




둘째 개발 효율성 측면 입니다. 이것 역시 자바를 베이스로 하는 안드로이드의 압승입니다. 사실 돈 쓰는 것 이상으로 중요한 부분이기도 합니다.

윈도즈 모바일은 C/C++ 로 개발하게 되어 있습니다. (지금까지는 그래왔었습니다) C/C++ 은 개발 속도가 느리기 때문에 대부분의 개발자 들이 좋아하지 않는 언어로도 유명합니다.

아이폰은 C 에다가 Object Oriented 개념을 섞은 Object-C 라는 언어로 개발합니다. 엎어치나 메치나 제가 보기에는 C/C++ 계열입니다. 원래 인기 없는 언어였는데 아이폰 때문에 인기가 급 상승을 하고 있는 언어입니다.

안드로이드는 Java 로 개발을 합니다. 기존에 쓰고 있던 자바와는 좀 다르다고 하나 모바일 특성에 맞춘 것 외에는 일반적인 자바와 비슷합니다.

결국 개발할 때 세가지 플랫폼에서 가장 큰 차이는 포인터라고 볼 수가 있습니다.

저는 개발자로 살아온 인생 거의 모두를 C/C++ 개발하는 데 쏟았습니다. 저는 C/C++ 이 아주 몸에 익었기 때문에 포인터(Pointer)를 잘 이해하고 실전(?)에서도 자주 쓰는 편입니다. 그런데 이 포인터라는 것이 안 쓰다 보면 아주 귀찮아 지는 종류 입니다. 개발을 3년 넘게 쉬었다가 아이폰쪽 개발을 할 때 간만에 만나는 포인터가 저를 당황케 하더군요. 그런 의미에서 자바는 아주 훌륭하더군요. 가비지 컬렉션이 되는 것만으로도 이리 쉽게 프로그래밍을 할 수가 있구나. 라는 것을 느꼈습니다.

Java 나 Object-c 나 제 입장에서는 처음 배우는 언어인 데도 여타 다른 프로그래머 분들과 마찬가지로 자바쪽이 훨씬 쉽습니다.오죽하면 미국 버클리대에서 프로그래밍 기초 신청하는 학생들이 포인터 진도 나갈 때 60% 가 수강 철회를 하느냐는 말도 나오지 않겠습니까?

포인터를 완벽하게 이해하고 있으면 '전산형 인간' (Homo Computeres) 으로 기존의 사람들과 종이 다르게 분류되도 할 말은 없겠네요. 

간단하게 개발자 측면에서만 살펴 봤습니다. 하지만 오픈 마켓이 아이폰이 잘 되어 있지 않느냐는 말을 정말 많이 들었습니다. 그렇습니다 "왜? 개발을 하는가"도 중요하기 때문입니다. 결국 프로그램을 만들면 팔아서 돈을 벌어야 하는데 그런 제반 환경이 아이폰쪽이 잘 되어 있습니다. 하지만 굳이 팔려고 프로그래밍을 안하더라도 자신의 폰에 자신만의 프로그램을 만들어서 넣어보려는 용도로도 개발자들은 움직입니다. 그리고 그런 용도라면 정말 안드로이드를 추천합니다.

마음 편히 시작하고 아니다 싶으면 바로 접을 수도 있습니다.




이 다중 뷰를 다루는 기술이 상단히 사람을 짜증나게 하는군요 -0- , 아예 인터페이스 설계를 다시 할까 생각중이긴 하지만 공부한다 치고 또 찾아 봤습니다.

요기 클릭

아주 훌륭하게 개념과 소스까지 전부 나열됐습니다. 그리고 납득이 가능하더군요. 뷰 컨트롤러 자체를 관리하는 appDelegate 에서 메시지 중재를 한다는 개념입니다.


맥을 얼마전에야 샀습니다. 그런데 주문한 날 새로운 OS가 나오더군요. 그래서 맥을 산곳에 전화를 해서 새로운 OS (Snow Leopard) 가 나온 것을 알고 있다. 빨리 한개 보내달라고 했습니다. -ㅅ- 물론 그쪽에서는 정중하게 되묻더군요 "머리에 구멍이라도 나셨습니까? 손님?" 네 그렇습니다. 저는 진상짓을 제대로 하기 시작했습니다. 회사에서 재무 보는 친구가 제 등쌀에 못이겨서 전화기를 들고 이야기를 하고 있고 저는 옆에서 어떻게 하겠다는 협박만 알려줬습니다. 착한 제 친구는 (재무 보는 친구) 땀을 뻘뻘 흘리면서 저의 온갖 진상짓을 마이너한 버젼으로 항의를 하더군요. 결국 '걍 환불하고 조금 기다렸다가 새 OS 장착 되는거 확인하고 사겠다' 라는 아주 멋진 협박을 알아내서 이야기 했더니 그쪽에서 바로 '이거나 먹구 떨어져라' 라는 식으로 OS 업그레이드 비용을 통장으로 부쳐주더군요.

뭐 열심히 얻어낸 쾌거였기 때문에 즐거워 하면서 운영체제를 업그레이드 했지만 새로받은 OS 는 64비트 전용이라 기존의 OS 에서 설치했던 프로그램들이 충돌나는 것이 몇개 있었습니다. 예전에 제가 올렸던 [[예전 포스팅]] 같은 경우 말이죠.

항상 새로운 것이 문제입니다. 새로운 것을 그냥 쓰는 것은 사실 문제가 되지 않지만, 잘 쓰거나 또는 뭔가 사람들이 잘 안하려는 것을 할려고 할 때는 더욱 더 문제가 되기 마련입니다.

아이폰 어플리케이션 개발이 바로 그런것이라고 볼 수가 있습니다.  예전 버젼이라면 문제가 없겠지만 아이폰 OS 가 최신인 3.1.2 를 쓰면 문제가 되고, 개발하는 OSX 가 10.6 (즉 Snow Leopard)가 되면 문제가 되기 마련이지요. 이 두가지가 결부된다면? 아 끔찍합니다..

바로 이러한 짜증을 바탕에 두고 이 작업을 시작했습니다. 결국 논점은 그것입니다. 개인용 제작시 우리돈으로 대략 년당 12만원 , 상업용 제작시 우리돈으로 대략 년당 120만원 이돈을 아껴볼려고 하기 때문입니다. 제가 상업용을 제작할 것도 아니고, 그렇다고 제작한 것을 외부에 공개할 것도 아니고 그냥 간단하게 제작해서 제 아이팟 터치에 넣어서 가지고 싶은 것인데 너무 돈이 비싸지요. 즉 라이센스 작업은 나중에 공개할 때 해도 충분하다는 것입니다.

물론 쉬운 작업은 아니였습니다. 해놓구 보면 쉽지만 하기까지의 과정이 쉽지 않더군요. 물론 어려운 이유는 자료가 없어서 입니다. 정말 찾기 힘든 자료들과 된다고 쓰여져 있는데 안되는 것들 이러한 것들이 총체적으로 난항을 겪게 했습니다. 더러워서 돈 내고 받아볼까? 라는 생각까지 해봤습니다. ^^;;

아이폰 jailbreak 에 대해서는 굳이 설명 드리지 않겠습니다. 하는 법도 어렵지 않고 또 jailbreak 도 못하신다면 거기서 돈안내고 개발은 포기하시는게 정신 건강상 좋습니다. 제가 쓰는 방법은  blackra1n 이라는 툴을 쓰는것입니다. 지금까지 나온 방법중에서 가장 혁신적인 원버튼 해킹이 됩니다. 구글에서 'blackra1n'을 검색해보시면 바로 프로그램 뜹니다.

아이폰 (또는 아이팟 터치)이 '탈옥'이 됐으면 이제 개발에 들어갈 차례입니다. apple 의 Developer 사이트에서 iphone_sdk_3.1.2_with_xcode_3.2.1__snow_leopard__10m2003.dmg 를 다운 받습니다. 버젼과 OS 확인하시고 받으시면 됩니다. 이 글을 쓰는 당시는 저 버젼이 최신이였습니다. 그리고 바로 설치해 주시고요. 그러면 컴퓨터에 Xcode 3.2.1 버젼이 설치되었을 것입니다.

XCode 를 실행하고 다음 그림과 같이 "Create a new Xcode project" 를 선택합니다.

Welcome to Xcode

이런 툴을 공짜로 배포하는 애플이라니!! 하지만 인증서로 돈 계속 받으니 MS 가 나은건가?..



테스트할 것이기 때문에 프로젝트 종류는 아무거나 선택합니다.


Window-based Application

윈도우 베이스 어플리케이션으로 테스트



프로젝트 이름을 정하는 것입니다. 이거도 아무거나 선택합니다. 저는 "Crazy World" 라고 정했군요.


New Project

헬로 월드가 식상해서...



자 일단 컴파일을 해보면 Simulator 로는 잘 되는 것을 확인할 수 있습니다. 이제 Device - 3.1.2 로 바꾸고 컴파일을 해봅니다. 잘 컴파일이 되고 인스톨이 된다면 성공이겠지만. 당연히 안 될 것입니다. 


Device - 3.1.2

디바이스에서 프로그램을 돌릴꺼라는 이야기입니다.




정확히는 컴파일이 안될 것입니다. 일단 컴파일 부터 되게 만들어 보겠습니다.

참조: http://networkpx.blogspot.com/2009/09/compiling-iphoneos-31-apps-with-xcode.html

여기에서 참조하실 부분이 'I want to compile' 부분 입니다. 조금 정리를 하자면

1. 자체 제작할만한 인증서가 필요합니다. 인증서를 만드는 방법은 여기에서 인증서를 만드는 방법이 있습니다.  인증서 만들때 Name (이름) 을 'iPhone Developer' 로 만들어 주는 것만 확인하시면 됩니다.

2. 만들어진 인증서는 '로그인' 키체인에 존재해야 합니다. 절대 '시스템' 키체인이 아닙니다. 그리고 모든 사용자에게 신뢰하겠냐는 부분은 하겠다고 체크하셔야 합니다.

3. 인증서가 만들어졌으면 다음과 같은 작업을 해줘야 합니다.

   3-1. /Developer/Platforms/iPhoneOS.platform/Info.plist 파일을 열어서
   3-2. 46 번째 줄에서 XCiPhoneOSCodeSignContext 를 XCCodeSignContext 로 바꾸어 줍니다.
   3-3. 79 번째 줄에서 XCiPhoneOSCodeSignContext 를 XCCodeSignContext 로 바꾸어 줍니다.
   3-4. 파일 저장합니다.
   3-5. XCode 를 재시작합니다.

4. 이제부터 컴파일이 아주 부드럽게 될 것입니다.


그리고 그 다음부터 참조한 페이지에서 나오는 'I want to install and debug too' 부분은 열심히 따라 했지만 아이팟 터치만 두 세번 복원하고 안된다는 것만 확인했습니다. 모름지기 하는 방법이 복잡한 것 치고 좋은 방법이 없다는 것을 다시 한번 확인한 셈이라 볼 수 있습니다.참조 페이지를 쓰신 분은MobileInstallation.framework 을 안좋아 하신다는 것이 힌트가 되서 MobileInstallation.framework 방법으로 성공했습니다. 그 방법을 알아보기로 하지요. 매우 쉽습니다.

참조: http://www.iphonedownloadblog.com/2008/08/18/mobileinstallation-for-iphone/

위 참조 사이트에서 'MobileInstallation patch for iPhone 3.1.2 Firmware:' 부분을 참조하시면됩니다. 

1. 아이폰이나 아이팟 터치에서 Cydia 를 실행시킵니다.

2. 아래쪽 탭에 있는 'Manage' -> 가운데에 있는 'Sources' -> 상단 오른쪽에 있는 'Edit' 클릭 ->  상단 왼쪽에 있는 'Add' 클릭

3. http://cydia.hackulo.us 입력하시고 'Add Source' 버튼 클릭

4. 'Add Anyway' 버튼 클릭 후 안정적으로 추가되면 아이폰(아이팟 터치)을 리부팅 시킵니다.

5. Cydia 를 실행시키고 하단 탭의 'Search' 를 클릭하고 "AppSync for OS 3.1' 을 설치합니다. 그리고 리부팅을 다시 한번 해줍니다.

이제 정상적으로 컴파일이 되고 아이팟 터치에 인스톨까지 되는 것을 확인하실 수가 있습니다. 년당 12만원을 아주 손쉽게 아꼈군요..


+ Recent posts