UIWindow's makeKeyAndVisible and background task



我已经将后台任务功能添加到我的应用程序中。这是我的应用程序代表

// 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
}

当用户点击应用程序图标时,应用程序的工作方式与我预期的一样。我在控制台上看到"确实出现了",然后事情就如我所料地发生了。

但当应用程序唤醒以执行后台任务(用户不可见)时,RootViewController's viewDidAppear仍因该线路而被调用

[self.window makeKeyAndVisible];

通过调用makeKeyAndVisible,它使RootViewController可见,即使它只在后台任务中处于唤醒状态。要解决此问题,我必须将此行移动到applicationDidBecomeActive

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

因此,现在仅当应用程序处于前台(用户可见)时才调用RootViewController's viewDidAppear。但是,我担心的是,当应用程序在设备内存中(活动或非活动)时,applicationDidBecomeActive将被调用多次。

  • 用户启动应用程序
  • 应用程序从跳板重新激活
  • 设备解锁
  • 结束呼叫

如果我在应用程序生命周期中多次调用UIWindow's makeKeyAndVisible,会有什么问题吗?

您可以轻松地确保makeKeyAndVisible只发生一次:包装它。

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

最新更新