2012-09-24 3 views
11

상태 저장을 위해 iOS 6 API를 구현했습니다. 작동합니다. 앱을 종료하고 몇 밀리 초 동안 다시 시작한 후 복원 된보기 컨트롤러가 작동하지만 메인보기로 바뀝니다. 컨트롤러를 시작할 때 표시합니다.ios 6 - 상태 보존 및 복원

앱이 주 창의 루트보기를 시작할 때마다 설정하므로 문제가되어야합니다. 내 윈도우의 루트보기를 설정하고있어 (있는 NSDictionary *) launchOptions : - (무효) commonInitializationLaunching

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    [self commonInitializationLaunching:launchOptions]; 
    return YES; 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    [self commonInitializationLaunching:launchOptions]; 
    return YES; 
} 

- (void)commonInitializationLaunching:(NSDictionary *)launchOptions 
{ 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 

     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     // Override point for customization after application launch. 
     static NSString *const kKeychainItemName = @"OAuthGoogleReader"; 
     self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; 
     self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 

     GTMOAuth2Authentication *auth; 
     auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName 
                    clientID:kClientID 
                   clientSecret:kClientSecret]; 

     self.window.rootViewController = self.navController; 

     [self.window makeKeyAndVisible]; 

     BOOL isSignedIn = [auth canAuthorize]; 
     if (isSignedIn) { 
      NSLog(@"Signed"); 
     }else{ 
      NSString *scope = @"https://www.google.com/reader/api/"; 

      GTMOAuth2ViewControllerTouch *viewController; 
      viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scope 
                     clientID:kClientID 
                    clientSecret:kClientSecret 
                   keychainItemName:kKeychainItemName 
                     delegate:self 
                   finishedSelector:@selector(viewController:finishedWithAuth:error:)]; 
      [self.navController pushViewController:viewController animated:YES]; 
      //  self.window.rootViewController = viewController; 
     } 
    }); 
} 

당신은 그의를 볼 수 있습니다

여기 내 코드입니다. 나는 거기에 무엇을 넣을 지 모른다. 아마도 저장된 상태가 있는지 확인한 다음이 방법을로드 할 것입니까? 그러나 어떻게?

감사합니다. 여기

내가 롭의 조언 다음 시도했습니다 것입니다 : willFinishLaunching에 아무것도

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    if (!self.isRestored) { 
     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    } 
    [self commonInitializationLaunching:launchOptions]; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

... 나는 또한 내 commonInitializationLaunching 방법에서 윈도우 코드에 의해 제거.

+0

내 대답이 도움이 되었습니까? 일부 의견은 훌륭합니다. – rbrown

답변

24

스토리 보드는 창 복원과 같은 대부분의 어려운 작업을 처리합니다. 그러나 코드를 사용하면 창을 복원하지 않습니다. 인코더를 사용하여 루트보기 컨트롤러를 고정해야합니다.코드는 다음과 같을 것이다 :

NSString * const AppDelegateRootVCKey = @"AppDelegateRootVCKey"; 

- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { 
    [coder encodeObject:self.window.rootViewController forKey:AppDelegateRootVCKey]; 
} 

- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { 

    // Grabs the preserved root view controller. 
    UIViewController * vc = [coder decodeObjectForKey:AppDelegateRootVCKey]; 

    if (vc) { 
     UIWindow * window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     window.rootViewController = vc; 
     window.restorationIdentifier = NSStringFromClass([window class]); 

     // The green color is just to make it obvious if our view didn't load properly. 
     // It can be removed when you are finished debugging. 
     window.backgroundColor = [UIColor greenColor]; 

     self.window = window; 
    } 
} 

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

    if (!self.window) { 

     UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 

     // The blue color is just to make it obvious if our view didn't load properly. 
     // It can be removed when you are finished debugging. 
     window.backgroundColor = [UIColor blueColor]; 

     UIViewController *root = // However you create your root. 

     window.rootViewController = root; 
     window.restorationIdentifier = NSStringFromClass([window class]); 

     self.window = window; 
    } 

    [self commonInitializationLaunching:launchOptions]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

조심하는 또 다른 잡았다이 UINavigationController들과 UITabBarController의가 복원 식별자를 가지고 있는지 확인하는 것입니다.

+0

내 테스트 프로그램에서 구현할 수는 없지만 다른 시간에 그것을 남겼다면 정말 논리적 인 것처럼 보입니다. 좋은 답변 주셔서 감사합니다! – Devfly

6

상태 복원은 일반적으로 스토리 보드와 통합됩니다. 스토리 보드를 사용하는 경우 자신 만의 창을 만들고 컨트롤러를 보는 등의 일을해서는 안됩니다. 스토리 보드에서이 작업을 수행하도록해야합니다. 스토리 보드가 모든 상태 복구를 수행하고 나서 새로운 창을 만들고 모든 창 위에 놓는 것이 발생합니다. 그렇다면 매번 출시 할 때마다 UI 복사본을 두 개 만들 것입니다. 너는 단지 그것을 알아 차리지 못하고있다.


당신이 코드의 전체 인터페이스를 구축하는 경우 (권장되지 접근 방식을하지만,이 작업을 수행)는, 당신은 상태 복원이 UI를 작성하기 전에 무슨 일이 있었 여부를 결정해야합니다. 이것은 매우 간단하다 : 당신의 commonInitializationLaunching:에서

  • 만이 아닌 UI 요소 (지금 상태로 보존 될하지 않을 것)를 초기화합니다. UI 요소가 상태 복원 중에 의존 할 수있는 것들을 처리 할 장소입니다. 현재 코드에는 이들 중 하나도 없습니다.

  • application:didDecodeRestorableState:에서 상태가 복원되었음을 나타내는 앱 대표 ivar를 설정합니다.

  • application:didFinishLaunchingWithOptions:에서 commonInitializationLaunching:을 실행 한 후 ivar를 확인하십시오. 상태가 복원되지 않으면 UI를 만듭니다.

당신은 그럼 그냥 didFinish에서 UI willFinish과 비 UI를 넣어 것을 필요로하지 않는 경우 commonInitializationLaunching: 패턴은 아이폰 OS 5와 이전 버전과의 호환성을 위해 존재한다는 것을 기억하십니까 (상태가 복원되지 않은 경우) .

+0

스토리 보드를 사용하지 않습니다. – Devfly

+0

정말 좋은 접근 방식이지만, 이제는 모두 검은 색 화면입니다. - 'self.windows makeKeyAndVisible'을 iVar'isRestored'에 의존하도록 움직일 때 나는 Storyboard가있는 간단한 마스터 - 디테일 앱으로 시도해 보았습니다. 나는 실종 됐어? – Devfly

+0

모든 경우에 -makeKeyAndVisible을 호출해야합니다. 복원하지 않을 때는 UIWindow 만 * 만들어야합니다. –