Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  SafeViewController.swift   Sprache: JAVA

 

import CocoaLumberjackSwift
import ThreemaMacros
import UIKit

final class SafeViewController: IDCreationPageViewController, IntroQuestionDelegate {
    
    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var descriptionLabel: UILabel!
    @IBOutlet var passwordField: SetupTextField!
    @IBOutlet var passwordAgainField: SetupTextField!
    @IBOutlet var advancedOptionsButton: SetupButton!
    
    @objc var setupConfiguration: SetupConfiguration!
    
    var didShowAlert = false
    var didShowConfirm = false
    
    var customServer: String?
    var server: String?
    var serverUsername: String?
    var serverPassword: String?
    var maxBackupBytes: Int?
    var retentionDays: Int?
    
    var passwordAgainOffset: CGFloat = 0
    
    var mdmSetup: MDMSetup
    
    required init?(coder aDecoder: NSCoder) {
        self.mdmSetup = MDMSetup()

        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        overrideUserInterfaceStyle = .dark

        hideKeyboardWhenTappedAround()

        titleLabel.text = String.localizedStringWithFormat(
            #localize("safe_setup_backup_title"),
            TargetManager.localizedAppName
        )
        descriptionLabel.text = String.localizedStringWithFormat(
            #localize("safe_setup_backup_description"),
            TargetManager.localizedAppName
        )
        
        passwordField.delegate = self
        passwordField.placeholder = #localize("Password")
        passwordAgainField.delegate = self
        passwordAgainField.placeholder = #localize("password_again")
        advancedOptionsButton.setTitle(#localize("safe_advanced_options"), for: .normal)
        advancedOptionsButton.cancelStyle = true
        advancedOptionsButton.isHidden = mdmSetup.isSafeBackupForce() || mdmSetup.isSafeBackupServerPreset()
        
        moreView.mainView = mainContentView
        moreView.moreButtonTitle = #localize("more_information")
        moreView.moreMessageText = String.localizedStringWithFormat(
            #localize("safe_enable_explain"),
            TargetManager.localizedAppName
        )
        
        passwordAgainOffset = passwordAgainField.frame.origin.y
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        registerForKeyboardNotifications()
        UIAccessibility.post(notification: .screenChanged, argument: titleLabel)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        unregisterForKeyboardNotifications()
    }

    // MARK: - Navigation
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let safeServerViewController = segue.destination as? SafeServerViewController else {
            return
        }
        
        mainContentView.isHidden = true
        moreView.isHidden = true
        containerDelegate.hideControls(true)
        
        safeServerViewController.customServer = customServer
        safeServerViewController.server = server
        safeServerViewController.serverUsername = serverUsername
        safeServerViewController.serverPassword = serverPassword
    }
    
    private func validatedPassword() -> String? {
        
        if let password = passwordField.text {
            if let regExPattern = mdmSetup.safePasswordPattern() {
                do {
                    if try !SafeManager.isPasswordPatternValid(password: password, regExPattern: regExPattern) {
                        if let message = mdmSetup.safePasswordMessage() {
                            let alert = IntroQuestionViewHelper(parent: self, onAnswer: nil)
                            alert.showAlert(message, title: #localize("Password"))
                        }
                        else {
                            let alert = IntroQuestionViewHelper(parent: self, onAnswer: nil)
                            alert.showAlert(
                                #localize("password_bad_guidelines"),
                                title: #localize("Password")
                            )
                        }
                        return nil
                    }
                }
                catch {
                    DDLogNotice("Threema Safe: Can't check safe password because regex is invalid")
                    let alert = IntroQuestionViewHelper(parent: self, onAnswer: nil)
                    alert.showAlert(
                        String.localizedStringWithFormat(
                            #localize("password_bad_regex"),
                            TargetManager.appName
                        ),
                        title: #localize("Password")
                    )
                    return nil
                }
            }
            else {
                if password.count < kMinimumPasswordLength {
                    let alert = IntroQuestionViewHelper(parent: self, onAnswer: nil)
                    alert.showAlert(
                        #localize("password_too_short_message"),
                        title: #localize("password_too_short_title")
                    )
                    return nil
                }
            }
            
            if let passwordAgain = passwordAgainField.text,
               !password.elementsEqual(passwordAgain) {
                
                let alert = IntroQuestionViewHelper(parent: self, onAnswer: nil)
                alert.showAlert(
                    #localize("password_mismatch_message"),
                    title: #localize("password_mismatch_title")
                )
                return nil
            }
            else {
                return password
            }
        }
        
        return nil
    }
    
    override func isInputValid() -> Bool {
        if moreView.isShown() {
            return false
        }
        
        if let password = passwordField.text,
           password.count <= 0, !self.mdmSetup.isSafeBackupForce(), didShowAlert {
            
            return true
        }
        else if let password = passwordField.text,
                !password.isEmpty, didShowConfirm {
            
            return true
        }
        else if let password = passwordField.text,
                !password.isEmpty {

            // Keep custom safe backup server
            if let server {
                setupConfiguration.safeServer = server
                setupConfiguration.safeCustomServer = customServer
                setupConfiguration.safeServerUsername = serverUsername
                setupConfiguration.safeServerPassword = serverPassword
                setupConfiguration.safeMaxBackupBytes = maxBackupBytes as NSNumber?
                setupConfiguration.safeRetentionDays = retentionDays as NSNumber?
            }
            else {
                setupConfiguration.safeServer = nil
                setupConfiguration.safeCustomServer = nil
                setupConfiguration.safeServerUsername = nil
                setupConfiguration.safeServerPassword = nil
                setupConfiguration.safeMaxBackupBytes = nil
                setupConfiguration.safeRetentionDays = nil
            }

            if let validPassword = validatedPassword() {
                if SafeManager.isPasswordBad(password: validPassword) {
                    let alert = IntroQuestionViewHelper(parent: self) { _, answer in
                        if answer == .yes {
                            self.didShowConfirm = true
                            // store password temp. just in memory for setup completion process
                            self.setupConfiguration.safePassword = validPassword
                            self.containerDelegate.pageLeft()
                        }
                        else {
                            self.passwordField.becomeFirstResponder()
                        }
                    }
                    alert.showConfirm(
                        String.localizedStringWithFormat(
                            #localize("password_bad_explain"),
                            TargetManager.localizedAppName
                        ),
                        noButtonLabel: #localize("try_again"),
                        yesButtonLabel: #localize("continue_anyway")
                    )
                    
                    return false
                }
                
                // store password temp. just in memory for setup completion process
                setupConfiguration.safePassword = validPassword
                return true
            }
            
            return false
        }
        else if !mdmSetup.isSafeBackupForce() {
            let alert = IntroQuestionViewHelper(parent: self) { _, answer in
                if answer != .yes {
                    self.didShowAlert = true
                    self.containerDelegate.pageLeft()
                }
                else {
                    self.passwordField.becomeFirstResponder()
                }
            }
            alert.showConfirm(
                String.localizedStringWithFormat(
                    #localize("safe_disable_confirm"),
                    TargetManager.localizedAppName,
                    TargetManager.localizedAppName,
                    TargetManager.localizedAppName
                ),
                noButtonLabel: #localize("yes"),
                yesButtonLabel: #localize("no")
            )
        }
        
        return false
    }
}

extension SafeViewController {
    // private functions
    
    private func registerForKeyboardNotifications() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow),
            name: UIResponder.keyboardWillShowNotification,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }
    
    private func unregisterForKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self)
    }
    
    @objc private func keyboardWillShow(notification: Notification) {
        if passwordField.isFirstResponder {
            if let info = notification.userInfo {
                let keyboardScreenEndFrame = (info[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
                let keyboardRectConverted = view.convert(keyboardScreenEndFrame, from: view.window)
                let diff = keyboardRectConverted.minY - passwordField.frame.midY - 32.0
                
                if diff < 21.0 {
                    passwordField.isHidden = false
                    passwordAgainField.isHidden = true
                }
            }
        }
        else if passwordAgainField.isFirstResponder {
            if let info = notification.userInfo {
                let keyboardScreenEndFrame = (info[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
                let keyboardRectConverted = view.convert(keyboardScreenEndFrame, from: view.window)
                let diff = keyboardRectConverted.minY - passwordAgainField.frame.midY - 32.0
                
                if diff < 0.0 {
                    passwordField.isHidden = true
                    passwordAgainField.isHidden = false
                    
                    var animationDuration = TimeInterval()
                    let options = ThreemaUtilityObjC.animationOptions(
                        for: notification,
                        animationDuration: &animationDuration
                    )
                    UIView.animate(withDuration: animationDuration, delay: 0, options: options, animations: {
                        self.passwordAgainField.frame = CGRectMake(
                            self.passwordAgainField.frame.origin.x,
                            self.passwordAgainField.frame.origin.y + diff,
                            self.passwordAgainField.frame.size.width,
                            self.passwordAgainField.frame.size.height
                        )
                    }) { _ in
                    }
                }
            }
        }
    }
    
    @objc private func keyboardWillHide(notification: Notification) {
        var animationDuration = TimeInterval()
        let options = ThreemaUtilityObjC.animationOptions(for: notification, animationDuration: &animationDuration)
        
        UIView.animate(withDuration: animationDuration, delay: 0, options: options, animations: {
            self.passwordAgainField.frame = CGRectMake(
                self.passwordAgainField.frame.origin.x,
                self.passwordAgainOffset,
                self.passwordAgainField.frame.size.width,
                self.passwordAgainField.frame.size.height
            )
        }) { _ in
            if self.passwordAgainField.isFirstResponder == false {
                self.passwordField.isHidden = false
                self.passwordAgainField.isHidden = false
            }
            else {
                if let info = notification.userInfo {
                    let keyboardScreenEndFrame = (info[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue)
                        .cgRectValue
                    let keyboardRectConverted = self.view.convert(keyboardScreenEndFrame, from: self.view.window)
                    let diff = keyboardRectConverted.minY - self.passwordAgainField.frame.midY - 32.0
                    self.passwordField.isHidden = diff <= 0.0 ? true : false
                }
                else {
                    self.passwordField.isHidden = false
                }
                self.passwordAgainField.isHidden = false
            }
        }
    }
}

// MARK: - SetupTextFieldDelegate

extension SafeViewController: SetupTextFieldDelegate {
    func editingChangedTextField(_ sender: SetupTextField, forEvent event: UIEvent) {
        didShowConfirm = false
    }
    
    func primaryActionTriggered(_ sender: SetupTextField, forEvent event: UIEvent) {
        if sender == passwordField {
            sender.resignFirstResponder()
            passwordAgainField.becomeFirstResponder()
        }
        else if sender == passwordAgainField {
            sender.resignFirstResponder()
        }
    }
}

extension SafeViewController {
    @IBAction func cancelSafeServer(_ segue: UIStoryboardSegue) {
        mainContentView.isHidden = false
        moreView.isHidden = false
        containerDelegate.hideControls(false)
    }

    @IBAction func okSafeServer(_ segue: UIStoryboardSegue) {
        guard let safeServerViewController = segue.source as? SafeServerViewController else {
            return
        }
        
        didShowConfirm = false
        
        mainContentView.isHidden = false
        moreView.isHidden = false
        containerDelegate.hideControls(false)
        
        customServer = safeServerViewController.customServer
        server = safeServerViewController.server
        serverUsername = safeServerViewController.serverUsername
        serverPassword = safeServerViewController.serverPassword
        maxBackupBytes = safeServerViewController.maxBackupBytes
        retentionDays = safeServerViewController.retentionDays
    }
}

extension SafeViewController {
    override func dismissKeyboard() {
        super.dismissKeyboard()
        
        passwordField.resignFirstResponder()
        passwordAgainField.resignFirstResponder()
    }
}

extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }
    
    @objc func dismissKeyboard() {
        view.resignFirstResponder()
    }
}

Messung
CHZG
849710093

¤ Dauer der Verarbeitung: 0.10 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104842
#Domains=499168