2011년 2월 24일 목요일

[iOS/Three20] TTNavigator 기초

TTNavigator는 Three20에서 지원하는 Navigation Controller를 편하게 쓸 수 있도록 만든 클래스다. 모양도 기존 네비게이션 컨트롤러와 동일하고 동작하는 것도 비슷하다. 단지, 코드량이 급격하게 줄어든다는 차이점이 있다. ;;

Three20의 공식 문서가 좀 빈약해서 샘플 소스에서 TTNavigator에 관한 기본 분석을 해 봤다.

가장 먼저 이 컨트롤러를 어떻게 만드느냐가 문제다. 일단 어플리케이션 딜리게이트의 applicationDidFinishLaunching 내부에서 다음 코드를 사용한다.

TTNavigator* navigator = [TTNavigator navigator];

따로 alloc 하거나 init하는 것도 없이, with...으로 시작하는 static 메서드를 호출하는 것도 아니고 걍 navigator를 가져오는 코드다. 하지만 이것 만으로 윈도우에 네비게이션 컨트롤과 UI가 붙어버린다.

이 navigator라는 메서드 내부에서 현재 윈도우를 찾아서 알아서 뷰컨트롤러를 생성해서 붙여주는 역활을 하는 것 같다.

그럼 실제로 네비게이션은 어떻게 할 수 있느냐.

TTNavigator와 함께 따라다니는 녀석이 TTURLMap이다. URL이라는 말이 나오면 무슨 웹브라우징 이라도 하는 것 처럼 느껴지는데 사실 비슷한 용도다. 웹이 http:// 를 사용한다면 Three20은 tt:// 를 사용한다는 거다.

TTURLMap* map = navigator.URLMap;

기본적으로 네비게이터 객체에 URLMap이 이미 만들어져 있다. 즉, 네이게이터는 URL을 이용해 뷰를 호출할 수 있다는 거다.

[map from:@"*" toViewController:[TTWebController class]];

이 줄을 해석하는데 애 먹었는데, 매우 단순하다. 일단 아무 URL이 오면 웹브라우저 컨트롤러를 띄운다는 의미다. 물론 이 후에 몇 가지 사용자 정의 URL을 추가하는데 그 추가된 URL이 아닐 경우를 의미하는 거라고 볼 수 있다.

[map              from:@"tt://test1" 
toSharedViewController:[Test1Controller class]];

tt://test1 라는 URL을 받으면 Test1Controller 라는 뷰컨트롤러를 띄우라고 알려준다. 단, 이 컨트롤러는 1개의 인스턴스만이 생성된다. (Shared 라는 이름에 유의)

[map        from:@"tt://test2" 
          parent:@"tt://root" 
toViewController:[Test2Controller class]];

tt://test2 라는 URL을 받으면 Test2Controller 라는 뷰컨트롤러를 띄운다.

TTCatalog 라는 샘플 소스에서 AppDelegate.m 의 내용을 보면 이런 URL Map을 엄청나게 만들어 놓는 것을 볼 수 있다. 이러면 URL만으로 뷰컨트롤러를 골라갈 수 있으니 정말 편하고 가독성도 좋아진다. (라고 느껴진다 -_-;;)

그렇다면 가장 기본적인 URL(측 첫 화면)은 어떻게 지정하는가.

if (![navigator restoreViewControllers]) {
    [navigator openURLAction:
        [TTURLAction actionWithURLPath:@"tt://test1"]];
}

restoreViewController가 어떤 의미인지는 잘 모르겠지만, 네비게이션은 하위윈도우를 띄웠다가 부모윈도우로 돌아올 수 있는 그런 류의 UI를 구현하는게 목적이다. 즉, restore라는 말은 원래(루트?) 윈도우로 돌아오는 상태라고 추측된다. 그렇다면 이 if문의 내용은 프로그램이 처음 실행되었을 때를 가정하고 있는 것으로 볼 수 있다.

(Apple Developer 사이트에서 긁어온 네이게이션 컨트롤 이미지)

그리고 navigator를 통해 openURLAction을 수행한다. 여기서는 tt://test1 이라는 URL을 지정했으니 아마도 Test1Controller라는 녀석이 화면에 뜰 것이다.

마지막으로 URL을 받는 부분은 따로 구현이 필요한 것 같다. Application Delegate 소스 내용에서 handleOpenURL 부분도 정의를 해야 할 것이다.

- (BOOL)application:(UIApplication*)application 
      handleOpenURL:(NSURL*)URL {
    [[TTNavigator navigator] 
        openURLAction:
            [TTURLAction actionWithURLPath:URL.absoluteString]];
    return YES;
}

navigator가 AppDelegate위에서 돌아가는 녀석인 만큼 navigator로 전달되는 URL을 이녀석이 받아서 처리하는 것 같다. 없으면 아마도 URL을 아무리 넣어도 화면이 안뜨겠지 아마. (추측일 뿐이다)

일단 기본적인건 여기까지. 추측성 내용이 끼어있어서 틀린 것이 있을지도 모르겠지만 그건 그 때 가서 수정해야겠다...

댓글 없음 :