Boolean возвращает ноль и не может получить доступ к значению из ответа на контроллере представления - PullRequest
0 голосов
/ 13 января 2020

У меня есть пользовательская модель, которая проверяет серверную часть, существует ли электронная почта, - затем я возвращаюсь обратно в viewcontroller и устанавливаю логическое значение, которое должно запускать функцию. Однако значение не изменилось, и я пытаюсь изменить это значение из пользовательской модели, но оно недоступно. Я понимаю, почему это не работает .. но не знаю, как решить проблему.

static func sendEmailWithResetLink(email: String) {
        let params : Parameters = [
            PARAM_EMAIL : email
        ]
        request(URL_RESET_PASSWORD as String, method: .post, parameters: params, headers: nil).responseJSON {
            (response: DataResponse<Any>) in
            hideProgress()
            print("this is response \(response)")
            switch(response.result)
                      {
                      case .success(_):
                       print("it did not fail")
                       let passwordResetVC = PasswordResetViewController()
                       passwordResetVC.hasFailed = false
                          break

                      case .failure(_):
                        print("it failed")
                        let passwordResetVC = PasswordResetViewController()
//here boolean is set that I am trying to access in viewcontroller 
                        passwordResetVC.hasFailed = true   
                          break
                      }
        }
    } 

Ответы [ 2 ]

1 голос
/ 14 января 2020

Выход из @Alexander - Восстановите Monica и, как я полагаю, какой код будет выглядеть для решения вашей проблемы.

Использование MVC:

В папке Models (data / logi c part)

public class User {
private var name: String!
private var userEmail: String!
public var hasFailed: Bool?

init() {
    name = ""
    userEmail = ""
    hasFailed = nil
}

public func setName(name: String) { self.name = name }

public func getName() -> String { return name }

public func setEmail(email: String) { userEmail = email }

public func getEmail() ->String { return userEmail }

public static func sendEmailWithRestLing(email: String) {
    // your other code

    switch response.result {
    case .success(_):
        //your code
        hasFailed = false
        break
    case .failuare(_):
        // your code
        hasFailed = true
        break
    }
}
}

Класс диспетчера пользователей, применяющий одноэлементный дизайн

final class UserManager {
private var user = User()
static let instance = UserManager()

private init(){}

public func userName(name: String) {
    if (name.count > 3) {
        user.setName(name: name)
    }
    else { print("user name is too short") }
}

public func userEmail(email: String) {
    if (email.count > 3) {
        user.setEmail(email: email)
    }
    else { print("user email is too short") }
}

public func getUserName() -> String {
    let name = user.getName()

    if (name.isEmpty) { return "user name is Empty" }

    return name
}

public func getUserEmail() -> String {
    let email = user.getEmail()

    if (email.isEmpty) { return "user email is Empty" }

    return email
}

public func doKatieTask(link: String) -> Int {
    guard let myValue = user.hasFailed else {
        return -1
    }

    if (myValue) { return 1}

    return 0
}
}

Итак, теперь в папке «Контроллеры» и, поскольку мы являемся отношением «один к одному», мы будем использовать делегат шаблон дизайна. Если бы был один-ко-многим с контроллером представления. Используйте наблюдателей.

class ViewController: UIViewController {

@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var  emailTextField: UITextField!

var _hasFail: Bool!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

@IBAction func doTask() {
    UserManager.instance.userName(name: nameTextField.text!)
    UserManager.instance.userEmail(email: emailTextField.text!)

    switch UserManager.instance.doKatieTask(link: emailTextField.text!) {
    case 0:
        _hasFail = false
        break
    case 1:
        _hasFail = true
        break
    default:
        print("hasFailed is nil")
        break
    }

    if let vc = storyboard?.instantiateViewController(identifier: "passwordVC") as? PasswordResetViewController {
        vc.modalPresentationStyle = .fullScreen
        vc.delegate = self
        self.present(vc, animated: true, completion: nil)
    }
}

}

extension ViewController: KatieDelegate {
var hasFailed: Bool {
    get {
        return _hasFail
    }
    set {
        _hasFail = newValue
    }
}
}

В PasswordReset UIViewController

protocol KatieDelegate {
    var hasFailed: Bool { get set }
}


class PasswordResetViewController: UIViewController {

@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!

var delegate: KatieDelegate?

override func viewDidLoad() {
    super.viewDidLoad()

    nameLabel.text = UserManger.instance.getUserName()
    emailLabel.text = UserManger.instance.getUserEmail()

    if let delegate = delegate {
        print("The value for has failed is: .....\(delegate.hasFailed)!")
    }
    else { print("error with delegate") }


}
}
1 голос
/ 14 января 2020

Вот что я бы предложил. Возможно, у вас уже есть некоторые из них:

  1. Создание PasswordResetViewController объекта имеет @IBAction func resetButtonClicked, запускаемый кнопкой или чем-то еще, что запускает процесс сброса пароля.
  2. Создайте UserManager класс. Этот класс отвечает за все активизации управления профилями в вашем приложении. Среди прочего, он имеет возможность сброса паролей пользователей. Это UserManager, вероятно, будет синглтоном, который пока что достаточно хорош.
  3. Создайте новый протокол UserManagerDelegate. Добавьте к этому все возможности, которые необходимы UserManager для информирования их о том, что произошло. Например: var passwordResetHasFailed: Bool { get set }.
  4. Расширение вашего PasswordResetViewController соответствия этому протоколу.
  5. Ваш V C получает ссылку на объект singleton UserManager, сохраняет его в экземпляре и использует его для доступа к общему объекту с этого момента.
  6. Сделайте так, чтобы ваш PasswordResetViewController зарегистрировался в качестве делегата в диспетчере пользователей, с userManager.delegate = self
  7. @IBAction func resetButtonClicked просто позвоните userManager.resetPassword()
  8. Ваш UserManager сделает все необходимое для сброса пароля пользователя.
  9. Когда это будет сделано, он вызовет self.delegate?.passwordResetHasFailed = true/false.
  10. Поскольку ваш PasswordResetViewController зарегистрировался в качестве делегата UserManager, когда операция будет завершена, его passwordResetHasFailed свойство будет изменено, что даст ему возможность ответить (обновив некоторый пользовательский интерфейс или что-то еще).

У этого подхода есть некоторые ограничения, но это неплохой способ начать работу. Обратите внимание:

  1. Это позволяет вам тестировать ваш PasswordResetViewController. Вы можете создать MockUserManager и установить tesPasswordResetViewController.userManager = MockUserManager(), что позволит вам отделить менеджер пользователя, и протестировать PasswordResetViewController изолированно.
  2. Вы столкнетесь с проблемами, если вам понадобится несколько объектов для подписки. получать обратные вызовы делегатов (поскольку может быть только 1 объект делегата). В этот момент вы можете переключиться на использование чего-то вроде Promises, RxSwift или Combine. Но это проблема на более позднее время, и миграция будет легкой.
...