2012-09-24 9 views
11

मैंने राज्य की बचत के लिए आईओएस 6 एपीआई लागू किया है, यह काम करता है - जब मैं ऐप छोड़ देता हूं और कुछ मिलीसेकंड के लिए वापस लॉन्च करता हूं तो पुनर्स्थापित दृश्य नियंत्रक उड़ता है, लेकिन फिर इसे मुख्य दृश्य से बदल दिया जाता है मैं लॉन्च पर प्रदर्शित नियंत्रक।आईओएस 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; 
     } 
    }); 
} 

आपको लगता है कि में देख सकते हैं:

यहाँ मेरी कोड है। मुझे नहीं पता कि वहां क्या रखा जाए। शायद जांचें कि क्या बचाया गया राज्य है और फिर इस विधि को लोड करें? पर कैसे?

धन्यवाद!

यहाँ है कि मैं क्या रोब की सलाह निम्नलिखित की कोशिश की है है:

- (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 और UITabBarController रों बहाली पहचानकर्ता बनाना है।

+0

आप उत्तर वास्तव में तार्किक लगते हैं, हालांकि मैं इसे अपने परीक्षण कार्यक्रम में लागू नहीं कर सका, और इसे किसी अन्य समय के लिए छोड़ दिया। महान जवाब के लिए धन्यवाद! – Devfly

6

राज्य बहाली आम तौर पर स्टोरीबोर्ड के साथ एकीकृत होती है। यदि आप स्टोरीबोर्ड का उपयोग कर रहे हैं, तो आपको अपनी खिड़की नहीं बनाना चाहिए, नियंत्रक देखें, आदि। आपको स्टोरीबोर्ड को यह आपके लिए करने देना चाहिए। क्या हो रहा है कि स्टोरीबोर्ड सभी राज्य बहाली कर रहा है, और फिर आप एक नई खिड़की बना रहे हैं और इसे सब के शीर्ष पर रख रहे हैं। यदि ऐसा है, तो आप शायद प्रत्येक लॉन्च पर अपने यूआई की दो प्रतियां बना रहे हैं। आप बस इसे ध्यान में नहीं देख रहे हैं।


आप कोड में अपने पूरे इंटरफ़ेस का निर्माण कर रहे हैं (एक सुझाई गई पहुंच नहीं है, लेकिन यह काम करता है), तो आप यह निर्धारित करने के राज्य बहाली अपने यूआई बनाने से पहले हुआ की जरूरत है। यह काफी सरल है:

  • अपने commonInitializationLaunching: में, केवल गैर UI तत्व (चीजें हैं जो कभी राज्य के संरक्षण में नहीं होगा) आरंभ कर देगा। यह उन चीजों को संभालने का स्थान है जहां यूआई तत्व राज्य बहाली के दौरान भरोसा कर सकते हैं। आपके पास वर्तमान कोड में इनमें से कोई भी नहीं है।

  • application:didDecodeRestorableState: में, एक ऐप प्रतिनिधि ivar सेट करें ताकि यह इंगित किया जा सके कि राज्य बहाल हो गया है।

  • application:didFinishLaunchingWithOptions: में commonInitializationLaunching: चलाने के बाद, अपने ivar की जांच करें। अगर राज्य बहाल नहीं किया गया था, तो यूआई बनाएं।

याद है कि commonInitializationLaunching: पैटर्न केवल iOS 5 के साथ पिछली संगतता के लिए मौजूद है आपको लगता है कि, तो बस didFinish में willFinish में और यूआई गैर यूआई डाल की जरूरत नहीं है (यदि राज्य को पुनर्स्थापित नहीं किया गया था) ।

+0

मैं स्टोरीबोर्ड का उपयोग नहीं कर रहा हूं। – Devfly

+0

वास्तव में अच्छा दृष्टिकोण है, लेकिन अब मुझे ब्लैक स्क्रीन मिलती है - जब मैं अपने '[self.windows makeKeyAndVisible] को iVar' isRestored 'पर निर्भर करता हूं, मैंने स्टोरीबोर्ड के साथ सरल मास्टर-विस्तार ऐप के साथ भी कोशिश की, और' टी काम किया .. क्या ऐसा कुछ है जो मुझे याद आ रहा है? – Devfly

+0

आपको सभी मामलों में कॉल -मेकके और दृश्यमान कॉल करने की आवश्यकता है। पुनर्स्थापित नहीं होने पर आपको बस * UI * विन्डो बनाना चाहिए। –

संबंधित मुद्दे