Eureka Swift: установка значения SwitchRow без запуска onChange - PullRequest
0 голосов
/ 09 апреля 2020

Я использую Eureka SwitchRow для включения аутентификации FaceID / TouchID. Ход процесса выглядит следующим образом:

  1. Пользователь включает SwitchRow для включения FaceID / TouchID
  2. Бросить предупреждение, чтобы подтвердить включение, если подтверждено, выполнить аутентификацию
  3. В случае отмены , верните SwitchRow в предыдущее состояние
  4. Если аутентификация прошла успешно, сохраните настройки в UserDefaults, в противном случае верните SwitchRow в предыдущее состояние.

Проблема Как вернуться к предыдущее состояние без запуска onChange?

В этом посте здесь предлагается использовать следующий код:

form.delegate = nil
row.value = "Your value"
form.delegate = self

Но он не возвращает SwitchRow в предыдущее состояние. Он сохранил SwitchRow в новом состоянии, но отсоединяет onChange при повторном нажатии SwitchRow.

<<< SwitchRow() {
    $0.title = "Enable FaceID/TouchID"
    $0.value = false
    }.onChange({ [weak form] in
        if let form = form, let state = $0.value {
            self.handleChange(state: state, switchRow: $0, form: form)
        }
})

func handleChange(state: Bool, switchRow: SwitchRow, form: Form) {
    //1. Throw alert to turn on
    //2. if ok to turn on, authenticate
    //3. Authenticated, save to userdefaults

    let message = state ? "Are you sure you wanna enable?" : "Are you sure you wanna disable?"

    let alert = UIAlertController(title: "Biometric unlock", message: message, preferredStyle: .alert)

    let onOffAction = UIAlertAction(title: "Yes", style: .default) { (_) in
        self.authenticateBiometric(state: state, switchRow: switchRow, form: form)
    }

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in
        self.reset(fromState: state, switchRow: switchRow, form: form)
    }

    alert.addActions([onOffAction, cancelAction])
    present(alert, animated: true, completion: nil)
}

func authenticateBiometric(state: Bool, switchRow: SwitchRow, form: Form) {
    var error: NSError?

    if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
        let reason = "Enable TouchID to unlock the app."

        context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { (success, error) in
            if let error = error {
                print("Error", error.localizedDescription)
                self.reset(fromState: state, switchRow: switchRow, form: form)
                return
            }

            if success {
                if state {
                    //Turning on
                    print("Turning on successful")
                } else {
                    //Turning off
                    print("Turning off successful")
                }
                UserDefaults.standard.set(state, forKey: "unlockWithBiometric")
                UserDefaults.standard.synchronize()
            } else {
                print("Failed")
                self.reset(fromState: state, switchRow: switchRow, form: form)
            }
        }
    }
}

func reset(fromState: Bool, switchRow: SwitchRow, form: Form) {
    DispatchQueue.main.async {
        form.delegate = nil
        switchRow.value = !fromState
        form.delegate = self
    }
}

Как можно вернуть switchRow обратно в предыдущее состояние, не вызывая onChange? Если onChange срабатывает, он перестанет работать на oop и начнет выдавать предупреждение снова и снова.

...