выполнить Segue Swift 4 - PullRequest
       15

выполнить Segue Swift 4

0 голосов
/ 18 мая 2018

Я пытаюсь подтвердить логин пользователя в моей базе данных. Когда кнопка входа в систему нажата, я хочу сказать, произойдет ли переход или нет, основываясь на информации, возвращенной из базы данных. Сначала я принимаю переменное решение, равное true, и если я не могу подтвердить пользователя, я хочу установить значение false и предотвратить переход. Это код, который у меня есть, но есть проблема с ним. Оператор return в конце всегда верен. В основном происходит возврат в конце после того, как .resume () будет вызван первым, прежде чем ответ будет возвращен из базы данных. Может кто-нибудь уточнить, почему это происходит

 override func shouldPerformSegue(withIdentifier identifier: String,sender: 
 Any?) -> Bool
 {
             var decision = true
            let url = URL(string:"http://192.23.25.98/login/php")
            var request = URLRequest(url: url!)
            request.httpMethod = "POST"
            let body = "UserNameLogIn=\(userName.text!.lowercased())&PasswordLogIn=\(passWord.text!.lowercased())"
            request.httpBody=body.data(using: String.Encoding.utf8)
            URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
                if (error == nil)
               {
                    DispatchQueue.main.async(execute: {
                        do
                        {
                            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? Dictionary<AnyHashable,AnyObject>
                            guard let parseJson = json else{
                                print ("error parsing")
                                return
                            }
                            let status = parseJson["status"]
                            if (status != nil)
                            {
                                if (parseJson.count>3)
                                {
                                    decision = true

                                }
                                else
                                {
                                    decision = false


                                }
                            }
                        }
                        catch
                        {

                            print("error: \(error)")
                        }
                    })
                }
                else
                {
                    decision = false
                }
                }.resume()
    return decision
}

1 Ответ

0 голосов
/ 18 мая 2018

Вместо того, чтобы инициировать переход по нажатию кнопки и пытаться перехватить асинхронный процесс в shouldPerformSegue(withIdentifier:sender:), вместо этого вам просто нужно задать кнопке определение @IBAction, которая выполняет запрос проверки и программно инициирует переход, если онуспешно.

Таким образом:

  1. Удалите переход от кнопки.

  2. Добавьте переход между контроллерами представления с помощью control -перемещение от иконки контроллера вида на панели над первой сценой ко второй сцене:

    enter image description here

  3. Выберите переход и дайте ему имя в инспекторе атрибутов:

    enter image description here

  4. Сняв переход с кнопки, выТеперь вы можете подключить вашу кнопку к методу @IBAction:

    enter image description here

  5. Ваше действие для входа должно performSegue(withIdentifier:sender:) когда вы закончите свою логику проверки:

    performSegue(withIdentifier: "NextSceneSegue", sender: self)
    

    Например

    @IBAction func didTapLoginButton(_ sender: Any) {
        let url = URL(string:"http://192.23.25.98/login/php")
        var request = URLRequest(url: url!)
        request.httpMethod = "POST"
        request.httpBody = ["UserNameLogIn": useridTextField.text!, "PasswordLogIn": passwordTextField.text!]
            .map { $0.key + "=" + $0.value.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)! }
            .joined(separator: "&")
            .data(using: .utf8)
    
        URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async {
                guard let data = data, let httpResponse = response as? HTTPURLResponse, (200 ..< 300) ~= httpResponse.statusCode, error == nil else {
                    // handle basic network errors here
                    return
                }
    
                guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else {
                    // handle json parsing errors here
                    return
                }
    
                if json["status"] == nil  {
                    // handle missing status here
                    return
                }
    
                guard json.count > 3 else {
                    // handle incorrect count here
                    return
                }
    
                self.performSegue(withIdentifier: "NextSceneSegue", sender: self)
            }
        }.resume()
    }
    
  6. Примечание,Я в процентах кодирую значения в теле запроса.Пароли, в частности, могут содержать зарезервированные символы.И я не ошибаюсь, используя .urlQueryAllowed, но вместо этого использовал .urlQueryValueAllowed, в котором я вытащил несколько зарезервированных символов:

    extension CharacterSet {
    
        /// Returns the character set for characters allowed in the individual parameters within a query URL component.
        ///
        /// The query component of a URL is the component immediately following a question mark (?).
        /// For example, in the URL `http://www.example.com/index.php?key1=value1#jumpLink`, the query
        /// component is `key1=value1`. The individual parameters of that query would be the key `key1`
        /// and its associated value `value1`.
        ///
        /// According to RFC 3986, the set of unreserved characters includes
        ///
        /// `ALPHA / DIGIT / "-" / "." / "_" / "~"`
        ///
        /// In section 3.4 of the RFC, it further recommends adding `/` and `?` to the list of unescaped characters
        /// for the sake of compatibility with some erroneous implementations, so this routine also allows those
        /// to pass unescaped.
    
        static var urlQueryValueAllowed: CharacterSet = {
            let generalDelimitersToEncode = ":#[]@"    // does not include "?" or "/" due to RFC 3986 - Section 3.4
            let subDelimitersToEncode = "!$&'()*+,;="
    
            var allowed = CharacterSet.urlQueryAllowed
            allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)
            return allowed
        }()
    
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...