Восстановление состояния приложения в iOS 13 при смене языка приложения в настройках swift - PullRequest
0 голосов
/ 23 октября 2019

Я успешно сохранил и восстановил состояние приложения, когда я изменил язык в настройках и вернулся в приложение со следующим кодом:

AppDelegate.swift:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        if #available(iOS 13.0, *) {
            // In iOS 13 setup is done in SceneDelegate
        } else {
            let navController = UINavigationController(rootViewController: IntroController())

            window = UIWindow()
            window?.rootViewController = navController 
            window?.makeKeyAndVisible()
        }

        return true
    }

    func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
        return true
    }

    func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
        return true
    }

    // MARK: UISceneSession Lifecycle

    @available(iOS 13.0, *)
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, viewControllerWithRestorationIdentifierPath identifierComponents: [String], coder: NSCoder) -> UIViewController? {
        return nil
    }

}

SceneDelegate.swift

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        window = UIWindow(windowScene: windowScene)

        if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
            configure(window: window, with: userActivity)
            return
        }

        let navController = UINavigationController(rootViewController: IntroController())
        window?.rootViewController = navController
        window?.makeKeyAndVisible()

    }

    func configure(window: UIWindow?, with activity: NSUserActivity) {
        let settingsController = SettingsController()
        let navController = UINavigationController(rootViewController: settingsController)
        settingsController.restoreUserActivityState(activity)

        window?.rootViewController = navController
        window?.makeKeyAndVisible()
    }

    func sceneWillResignActive(_ scene: UIScene) {
        if let navController = window!.rootViewController as? UINavigationController {
            if let settingsController = navController.viewControllers.last as? SettingsController {
                scene.userActivity = settingsController.settingsUserActivity
            }
        }
    }

    func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
        return scene.userActivity
    }
}

SettingsController:

struct Setting {
    var icon: UIImage
    var title: String
}

class SettingsController: UIViewController {

    private let tableView = UITableView()
    private let settings: [Setting] = [
        Setting(icon: #imageLiteral(resourceName: "icon-mail"), title: "Change mail"),
        Setting(icon: #imageLiteral(resourceName: "icon-camera"), title: "Change image"),
        Setting(icon: #imageLiteral(resourceName: "icon-language"), title: "Change Language"),
    ]

    @available(iOS 12.0, *)
    var settingsUserActivity: NSUserActivity {
        let activity = NSUserActivity(activityType: "restoration")
        activity.persistentIdentifier = UUID().uuidString
        return activity
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "Settings"

        setupTableView()
        setupView()
    }

    func setupTableView() {
        tableView.register(SettingsCell.self, forCellReuseIdentifier: "cellId")
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        tableView.backgroundColor = .white
        tableView.separatorInset = .zero
    }

    func setupView() {
        view.addSubview(tableView)
        tableView.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: view.leadingAnchor, bottom: view.safeAreaLayoutGuide.bottomAnchor, trailing: view.trailingAnchor)
    }
}

extension SettingsController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return settings.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! SettingsCell
        let setting = settings[indexPath.row]
        cell.setting = setting
        return cell
    }
}

extension SettingsController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        switch indexPath.row {
        case 0:
            let emailController = SettingsEmailController()
            navigationController?.pushViewController(emailController, animated: true)
        case 1:
            let photoController = SettingsPhotoController()
            navigationController?.pushViewController(photoController, animated: true)
        case 2:
            UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
        default:
            break
        }
    }
}

extension SettingsController {
    override func updateUserActivityState(_ activity: NSUserActivity) {
        super.updateUserActivityState(activity)
    }

    override func restoreUserActivityState(_ activity: NSUserActivity) {
         super.restoreUserActivityState(activity)
    }
}

Проблема в том, что «SettingsController» всегда восстанавливается и отображается, когда я перезапускаю приложение, а также когда я его убиваю и перезапускаю.

Чего я хочу добиться, так это восстанавливать «SettingsControler» только тогда, когда я изменяю настройки приложения броска языка и обратно в приложение, в противном случае я хочу показать «IntroController», в основном это использование «Восстановление состояния» для создания языкапереключение без шва, как предложено яблоком.

...