2012-09-24 16 views
11

我已經實現iOS 6中的API狀態保存,它的工作原理 - 在我退出程序,並在幾毫秒的恢復視圖控制器飛推出回來,但後來它是由主視圖替換我在啓動時顯示控制器。的iOS 6 - 國家保護修繕

我設置每次啓動應用程序主窗口的根視圖,所以這一定是這個問題。

這裏是我的代碼:

- (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; 
     } 
    }); 
} 

你可以看到,在 - (空)commonInitializationLaunching:(NSDictionary的*)launchOptions 我設置我的窗口的根視圖。我不知道該放什麼。也許檢查是否有保存狀態,然後加載這個方法?但是如何?

謝謝!

這裏是我試過以下羅布的建議是:

- (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; 
} 

有沒有在willFinishLaunching ... 我也通過窗口代碼中刪除從我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 S和UITabBarController■找恢復標識符。

+0

你的回答看起來很合理,但我無法在我的測試程序中實現它,並在其他時間出現。謝謝你的偉大答案! – Devfly

6

狀態恢復通常與故事板集成。如果你使用的是故事板,你不應該創建自己的窗口,視圖控制器等。你應該讓故事板爲你做這個。發生的事情是,故事板正在進行所有狀態恢復,然後您將創建一個新窗口並將其放在所有的窗口上。如果是這種情況,那麼您可能在每次啓動時創建兩個用戶界面副本。你只是沒有注意到它。


如果你正在構建在代碼的整個界面(不是推薦的方法,但它的工作),那麼你需要確定狀態恢復是否在創建用戶界面之前發生的事情。這是相當簡單:

  • 在你commonInitializationLaunching:,僅初始化非UI元素(事情不會永遠是在國家的保護)。這是處理UI元素在狀態恢復期間可能依賴的事情的地方。你目前的代碼中沒有這些。

  • application:didDecodeRestorableState:,將應用設置代表的ivar,以指示該狀態得到恢復。

  • application:didFinishLaunchingWithOptions:,運行commonInitializationLaunching:後,檢查你的伊娃。如果狀態未恢復,請創建一個UI。

千萬記得commonInitializationLaunching:模式只存在向後兼容的iOS 5,如果你不需要這一點,那麼只要把非UI在willFinish和UI在didFinish(如果未恢復狀態) 。

+0

我不使用故事板。 – Devfly

+0

真的很好的方法,但我現在得到的只是黑屏 - 當我移動我的'[self.windows makeKeyAndVisible]'取決於iVar'isRestored'時,我甚至用簡單的Master-Detail應用程序與Storyboard進行了試驗,工作..有什麼,我失蹤? – Devfly

+0

您需要在所有情況下調用-makeKeyAndVisible。在不恢復的時候,你應該只創建一個UIWindow。 –