처음 스위프트 (Swift : 혹 수입푸드 라고 부르는 사람들도 있음 ㅋㅋ) 개념을 보았을 때, VM (Virtual Machine) 같은 개념으로 여겼습니다. '뭐 또 빠르게 개발은 될 지 모르겠으나 동작은 느린애가 되겠군' 라고 생각하며 안 보고 있다가. 최근에 보니 이게 컴파일러용 언어였더군요. 플레이그라운드(Playground) 개념은 잽싸게 컴파일 해서 그 결과를 보여줘서 interactive 하게 보일지 모르지만 실은 컴파일 언어였습니다. 


개념이 재미 있는데다가 컴파일된 바이너리가 기존의 Object-C 언어로 만들어진 것보다 속도가 2.8 배가 빠르다는 것을 보고 관심이 가더군요. 그래서 언어 개요를 가볍게 살펴봤습니다. 

iOS 기기를 가지고 있으면 iBooks 에서 공짜로 프로그래밍 언어에 대해서 설명한 책을 받아볼 수가 있습니다. 물론 그런것이 없는 분들을 위해서 사이트에서도 제공됩니다. 그리고 정말 훌륭하신 분들이 해석해서 사이트에 올려둔 곳도 존재하더군요. 


Swift 언어 가이드 


에서 참조하실 수 있습니다. 저는 프로그래밍 언어 자체에 노력을 많이 기울이는 편은 아닙니다. 애초에 Swift 가 필요한 이유는 iOS 나 Cocoa 용 앱을 빠르게 만들기 위함이 아니겠습니까? 그렇다면 실전에서 익히고 어렵거나 이해가 안가는 부분을 찾아서 공부하는 것이 조금 더 '실용적' 이라고 생각하기 때문입니다. (실은 예전에 프로그래밍 언어 그 자체만 공부하다가 지치거나 중간에 흥미가 떨어져서 응용해 보지도 못한 적이 여러번 있기 때문입니다. - 마치 영어를 공부해야 하는데 어떻게 하면 영어 공부를 잘하는 법을 공부하는 경우와 비슷하다고 하겠습니다) 


그래서 실전 튜토리얼을 찾아보다가 찾은 정말 훌륭한 동영상이 있더군요. 비록 한글이나 한국어로 된 것은 아니긴 하지만 기술 영어를 사용하고 있어서 쉽게 알아먹을 수가 있습니다. 영어도 공부하고 Swift 도 공부하고 1석 2조!! 


프로그래밍 경험 없는 사람이 쉽게 iOS 용 앱 (다 만들면 게임이 만들어 집니다) 만들기 


iOS 용 앱을 만들어 볼려고 했는데 엄두가 안 나신분 들에게 강력 추천합니다. 내용중에 보면 MVC 패턴과 XCode 툴에 관한 설명등 들어두면 좋은 내용들 다수가 들어 있습니다. 



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 파일이 존재하는지 체크해서 존재 안하면 생성 시켜버렸습니다. 






+ Recent posts