2014-09-05 68 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