[OSX] 메인 윈도우 컨트롤러를 앱델리게이트에서 분리하기
iOS 앱의 경우에는 UIApplication 객체가 생성되면 해당 앱의 델리게이트가 런칭 직후의 일을 처리한다. 이 때 앱의 윈도우가 처음으로 표시할 초기 뷰 컨트롤러의 뷰를 윈도우에 보여주게 된다.
그 이후부터는 화면 단위로 각 뷰의 뷰 컨트롤러 및 여러 MVC의 컨트롤러와 여러가지 디자인패턴을 통해 상호작용하면서 앱을 구성하면 된다.
이에 비해 맥용 앱을 Xcode로 작성하고자 하면 이 “메인 컨트롤러”가 다름 아닌 앱 델리게이트 객체라는 점에서 좀 의아하게 생각된다. 즉, 메인 윈도우에 대해서는 별도의 컨트롤러가, 만약 또 다른 윈도를 생성한다면, 역시나 해당 윈도에 대해서는 별도의 컨트롤러가 있어야 하는 것 아니겠냐는 것이다.
이런 화면 단위마다 별도의 MVC를 구성하는 방법은 다음과 같다.
- 먼저 인터페이스 빌더 상에 초기에 생성된 MainMenu에 들어있는 윈도는 삭제한다.
- 메인 윈도우 뷰 컨트롤러로 쓸 객체를 새로 만든다. MainWindowController 정도?
- MainWindowController 객체를 MainMenu 파일에 추가한다. (NSObject를 추가해서 클래스 이름 변경)
- nib 파일을 새로 하나 생성한다. 이름은 MainWindow가 되면 되겠다.
- IB에서 새로 만든 메인 윈도우 nib의 File’s owner를 새로 생성한 윈도우 컨트롤러로 지정한다. 또한 이 인터페이스 파일의 윈도우를 MainWindowController의 window 아울렛과 연결해준다.
- 어플리케이션이 런칭되면서 MainMenu.nib 파일을 로딩한다.
- nib 파일이 로드되면 nib 파일 내에 정의된 객체를 초기화하고, 이 객체들에게 모두 awakeFromNib 메시지를 보낸다. 따라서 우리가 만든 윈도우 컨트롤러 객체도 이 메시지를 받게 될 것이다.
- 윈도 컨트롤러 객체에서 이 메시지를 받으면 메인 윈도우가 들어있는 nib 파일을 로드하고, 윈도를 표시하도록 한다.
@property (assign) IBOutlet NSWindow *window;
-(void)awakeFromNib { if (!self.window) [NSBundle loadNib:@"MainWindow" owner:self]; [self.window makeKeyAndFrontOf:self]; }
이제 앱을 빌드하고 실행해보면 해당 윈도우가 표시될 것이다.