2014-09-05 32 views
0

我已經將後臺任務功能添加到我的應用程序。這是我的應用程序委託UIWindow的makeKeyAndVisible和後臺任務

// AppDelegate.m 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]]; 
    [self.window setBackgroundColor:[UIColor blackColor]]; 

    if (application.applicationState != UIApplicationStateBackground) {   
     // Application is launch in because user tap the app icon or from springboard 

     if ([application respondsToSelector:@selector(setMinimumBackgroundFetchInterval:)]) { 
      [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; 
     } 
    } else { 
     // Application is launch in background mode 
    } 

    RootViewController *rootViewController = [[RootViewController alloc] initByDevice]; 
    [self.window setRootViewController:rootViewController]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 

    [[DataManager instance] updateDataWithMaxAttempt:5 block:^(BOOL success, NSArray *newData) { 
     if (success) { 
      if ([newData count] > 0) { 
       completionHandler(UIBackgroundFetchResultNewData); 
      } else { 
       completionHandler(UIBackgroundFetchResultNoData); 
      } 
     } else { 
      completionHandler(UIBackgroundFetchResultNoData); 
     } 
    }]; 
} 

這是我的根視圖控制器

// RootViewController.m 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    NSLog(@"Did appear"); 
    // Do something that I want it to happen only when the application is visible to user 
} 

當用戶點擊應用程序圖標,應用程序的工作原理是我所期待的。我在控制檯上看到「Did」,然後就像我期望的那樣發生了。

但是,當應用程序清醒,因爲這條線

[self.window makeKeyAndVisible]; 

通過調用makeKeyAndVisible的,它使RootViewController可見執行後臺任務(這不是對用戶可見)的RootViewController'sviewDidAppear仍然得到調用,即使它只是清醒爲後臺任務。爲了解決這個問題,我有這條線移動到applicationDidBecomeActive

- (void)applicationDidBecomeActive:(UIApplication *)application { 
    [self.window makeKeyAndVisible]; 
} 

其結果是,只有當應用程序在前臺RootViewController'sviewDidAppear現在正在通話(用戶可見)。但是,我擔心的是,當應用程序在設備內存中時(無論是活動還是非活動),applicationDidBecomeActive將被多次調用。

  • 用戶推出應用
  • 應用變得活躍起來,從跳板
  • 設備解鎖
  • 結束通話

是否有任何問題,如果我的應用程序生命週期中調用UIWindow'smakeKeyAndVisible幾次?

+1

我覺得'UIAlertView'或'UIActionSheet'會調用這個方法,因爲當它們顯示時,關鍵窗口被改變了。我認爲這不是在applicationDidBecomeActive中調用'[self.window makeKeyAndVisible]'的好方法,因爲那時可能會出現'UIAlertView'。 – KudoCC 2014-09-05 08:42:53

+0

@KudoCC感謝您的信息,我從來不知道這件事!你知道如果我顯示一個alertview - >鎖設備 - >解鎖它 - >調用[self.window makeKeyAndVisible]會發生什麼? – 2014-09-05 08:56:39

+1

很難說,這是一個不確定的行爲,你可以試一試。 – KudoCC 2014-09-05 09:00:11

回答

1

您可以很容易地確保makeKeyAndVisible只發生一次:包裝它。

if (!self.window.keyWindow) { 
    [self.window makeKeyAndVisible; 
} else if (self.window.hidden) { 
    self.window.hidden = NO; 
} 
+0

感謝您的解決方案亨利,我確實應用了類似於您的答案的東西。順便說一句,如果我多次調用makeKeyAndVisible,你知道會發生什麼嗎? (就像我在原始問題中的KudoCC的評論,他說UIAlertView和UIActionSheet也調用makeKeyAndVisible) – 2014-09-05 08:55:32

+1

我認爲這取決於上下文。它連續調用兩次,它可能不會做任何事情。我現在不在我的桌子上,但很容易檢查。無論如何,我更喜歡確保自己不需要依賴API邏輯內部需要。因此簡單的包裝。 – Rikkles 2014-09-05 09:03:19