iOS的UIApplicationExitsOnSuspend被弃用,有什么替代方案?

4

我有一个应用程序,我不希望它在后台运行。我的应用程序不能做任何后台模式下的操作,并且让它在后台运行只会增加烦人的用户界面复杂性。我希望应用程序在从前台移除时终止。

UIApplicationExitsOnSuspend是苹果之前允许实现此功能的方法,对于我的使用情况非常完美。然而,它现在已经被弃用了,他们拒绝具有该Info.plist值的应用程序。

我能找到的唯一替代方法是在应用程序委托方法中使用exit(0),但苹果强烈不建议这样做,而且它看起来像是一个崩溃。

还有其他可行的替代方案吗? 我只是不想让我的应用程序在后台运行,它只会不必要地耗费用户的电池电量。


3
如果您的应用程序没有任何操作,那么它就不会消耗电池电量。它会被暂停,什么也不做。从头重新启动应用程序将比从挂起状态恢复使用更多的电池电量。这就是为什么“滑动关闭”应用程序交换器中的所有应用程序是一个不好的习惯(同时还会阻止它们执行任何必需的后台任务)。 - Paulw11
1
我有一个类似的使用案例。我的应用程序要求在进入后台时退出,以便用户必须再次登录。我想我的另一个选择是允许应用程序进入后台,并在恢复时将它们放入登录序列中。 - acbush
1
顶一下并再次提问。我有一个应用,在退出时需要完全关闭,不允许后台或挂起任何形式的运行。UIApplicationExitsOnSuspend对此非常有效,我也不想使用exit(0)。 - GB540
如果您不明确允许应用程序的“后台模式”,则您的应用程序将不会执行任何操作,也不会消耗任何资源。 - Neekobus
这个标志的另一个重要用途是它可以避免各种可能的难以复现的错误。内存泄漏、在后台运行时间过长时触发Apple自己框架中的错误(WKWebView因此而臭名昭著)等等。我认为,在iOS中终止应用程序实际上应该是默认行为,甚至可以更进一步。 - Seven Systems
2个回答

0

对于SwiftUI,请将以下内容添加到App结构中:

@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

然后添加这两个类:

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
  ) -> UISceneConfiguration {
    let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
    sceneConfig.delegateClass = SceneDelegate.self // 
    return sceneConfig
  }

}

类 SceneDelegate: NSObject, UIWindowSceneDelegate {

func sceneWillResignActive(_ scene: UIScene) { // 这将强制应用程序在两秒后每次都重新启动(因此关闭动画看起来干净) do { sleep(2) } exit(0) } }


0
作为替代UIApplicationExitsOnSuspend,我在后台检查经过的时间并在需要时重置导航:
  • 我保留应用程序进入后台的最后时间(在applicationDidEnterBackground中使用NSUserDefaults
  • 当应用程序再次变为活动状态时,在applicationDidBecomeActive中检查保存的时间与给定的时间阈值。
  • 如果我的阈值超过了,我将重置我的导航(这使我可以在一些时间后重新同步我的应用程序或重新请求登录,但允许快速电话呼叫)
由于这是一个旧应用程序,这里是Objective-C代码:

appdelegate.m :

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"APPLIFE : going to sleep ... ");
    [[NSUserDefaults standardUserDefaults] setObject: [NSDate date] forKey:@"last-background-time"];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {

    NSLog(@"APPLIFE : ... back to front");
    NSDate * bgTime = [[NSUserDefaults standardUserDefaults] objectForKey:@"last-background-time"];

    NSTimeInterval secondsSinceLastRun = fabs([bgTime timeIntervalSinceNow]);
    double threshold = 60 * 60 * 24; //in seconds.   

    if (secondsSinceLastRun > threshold) {
        NSLog(@"APPLIFE : Too old, reboot app");
        //[navigationController popToRoot] or whatever you want
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接