Запрос POST дает тайм-аут при тестировании на устройстве iPhone

Я работаю над школьным проектом, который разрабатывает веб-приложение с API и приложением для iPhone с быстрым. Я разработал веб-сайт в Laravel с помощью Homestead/Vagrant.

Но когда дело доходит до приложения для iPhone, я сталкиваюсь с проблемой: когда пользователь нажимает кнопку входа в систему, приложение отправляет HTTP-запрос POST в API, и API проверяет, существуют ли пользователи в БД, и если да, то вернет токен, после чего пользователь будет перенаправлен на панель инструментов. Это отлично работает на симуляторе xcode.

Мой код части запроса выглядит так:

var loginUrl = "http://10.1.1.33/api/login" + "?email=" + self.email + "&password=" + self.password

let request = NSMutableURLRequest(URL: NSURL(string: loginUrl)!)

            let session = NSURLSession.sharedSession()
            request.HTTPMethod = "POST"

            let task = session.dataTaskWithRequest(request, completionHandler: {
                data, response, error -> Void in

                guard error == nil else {
                    print("First Error!!! \(error)")
                    self.errorLabel.text = "Request timed Out"
                    self.enableLoginBtn(true, buttonText: "Login")

                    return
                }

                do {
                    let data: AnyObject? = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
                    // Okay, the `json` is here, let's get the value for 'success' out of it

                    let json = JSON(data!)

                    dispatch_async(dispatch_get_main_queue(), {

                        if json["token"] != nil {

                            print("Login successvol!)")


                            if self.saveSession(json["token"].string!) {
                                self.enableLoginBtn(true, buttonText: "Login")
                                self.goToDashboard()
                            }else {
                                print("Saving token went wrong")
                            }


                        }else {
                            self.showError("Gebruikersnaam of wachtwoord is onjuist")
                            self.enableLoginBtn(true, buttonText: "Login")
                        }

                    })


                }catch let parseError{
                    print(parseError)
                    let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                    print("Error could not parse JSON: \(jsonStr)")
                    self.enableLoginBtn(true, buttonText: "Login")
                }
            })

            task.resume()

Но когда я пытаюсь протестировать то же самое на своем iPhone 5s (у меня есть лицензия разработчика), каждый раз происходит сбой. Ошибка, которую я получаю:

Домен ошибки = код NSURLErrorDomain = -1001 «Время ожидания запроса истекло». UserInfo=0x1742e1e80 {NSUnderlyingError=0x170259230 "Операция не может быть завершена. (kCFErrorDomainCFNetwork error -1001.)", NSErrorFailingURLStringKey=http://10.1.1.33/api/[email protected]&password=sndxbdj, NSErrorFailingURLKey=http://10.1.1.33/api/[email protected]&password=sndxbdj, NSLocalizedDescription =Время ожидания запроса истекло.}

Последние пару дней я перерыл весь интернет в поисках решения, но так и не нашел.

Буду очень признателен, если кто-то поможет мне с этим.

Заранее спасибо.

С наилучшими пожеланиями

EDITED -------------------- Скриншот ошибки введите здесь описание изображения


person O.S.Kaya    schedule 20.10.2015    source источник
comment
Может быть, проблема как-то связана с сетью? Вы разрабатываете Mac, который также подключается к серверу через Wi-Fi, как и ваш телефон?   -  person dirtydanee    schedule 20.10.2015
comment
Мой Mac достигает сервера. Работает как часы. Но когда дело доходит до тестирования на моем iPhone, он терпит неудачу.   -  person O.S.Kaya    schedule 20.10.2015
comment
Есть ли на вашем сайте стандартные HTML-страницы по адресу 10.1.1.33? Вы видите их нормально в браузере на вашем телефоне?   -  person Matt Gibson    schedule 20.10.2015
comment
Все на веб-сайте также работает нормально, даже если я делаю POST-запрос с параметрами URL, как объясняет Деян Скледар ниже.   -  person O.S.Kaya    schedule 20.10.2015
comment
он заблокирован, и вам нужно указать свой идентификатор в белый список? попробуйте создать точку доступа на своем компьютере Mac, подключите свой iPhone к этой точке доступа и попробуйте   -  person Omkar Guhilot    schedule 20.10.2015
comment
@OmkarGuhilot Я попробую вашу альтернативу, когда приведенное ниже решение не работает. Я собираюсь проверить это сейчас.   -  person O.S.Kaya    schedule 20.10.2015
comment
@OsmanSafaKaya ты пробовал?   -  person Omkar Guhilot    schedule 21.10.2015
comment
@OmkarGuhilot Создание точки доступа на моем Mac не сработало, мой телефон не смог найти точку доступа моего Mac. Поэтому я не смог протестировать приложение. Я очень ценю вашу помощь, хотя!   -  person O.S.Kaya    schedule 21.10.2015


Ответы (2)


Я думаю, вас могут смутить запросы POST и GET.

Параметры POST отправляются в теле запроса, а в запросе GET параметры отправляются в URL.

Пример параметров метода GET:

/test/demo_form.asp?name1=value1&name2=value2

Пример параметров метода POST:

POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2

Итак, что вы пытаетесь сделать, это отправить параметры в URL с запросом POST, поэтому это не работает!

Вам нужно указать параметры в теле запроса!

Что вам нужно сделать, это:

1. Измените URL-адрес запроса

var loginUrl = "http://10.1.1.33/api/login"

2. Добавьте параметры в тело запроса.

let postString = "email=" + self.email + "&password=" + self.password
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
person Dejan Skledar    schedule 20.10.2015
comment
Это совершенно верно и хороший совет, но я не уверен, что это объясняет реальную проблему в вопросе, то есть тайм-аут сети. - person Matt Gibson; 20.10.2015
comment
Большое спасибо за ваш ответ. Это действительно имеет смысл... Сейчас я направляюсь в аэропорт, вы услышите от меня как можно скорее, когда я протестирую ваш код - person O.S.Kaya; 20.10.2015
comment
@MattGibson Да, это действительно не должно истечь время ожидания, но мы не знаем, как настроен сервер. Это определенно начало. - person Dejan Skledar; 20.10.2015
comment
@DejanSkledar Извините, что это заняло так много времени. Только что вернулся и сразу протестировал решение, которое вы написали. Но, к сожалению, это не работает на моем устройстве. В симуляторе так. Я добавил скриншот ошибки, которую я получаю, когда запускаю его на своем устройстве. - person O.S.Kaya; 20.10.2015
comment
Попробуйте пропинговать сервер или получить доступ к серверу через Postman, чтобы проверить, работает ли сервер должным образом. - person Dejan Skledar; 20.10.2015
comment
Вы со своим телефоном в той же сети, что и с Mac? Попробуйте пропинговать сервер с телефона - person Dejan Skledar; 20.10.2015

Если вы используете iOS 9, это связано с новой настройкой безопасности транспорта, которая включена по умолчанию. Он блокирует все исходящие запросы без https. Есть способ отключить его для всех запросов, чтобы загружался любой http-запрос. Существует также способ управления каждым URL-адресом или подстановочным знаком URL-адреса, который может загружаться по http.

Если вы используете http для входа в систему, я предлагаю вам изменить свой сервер для поддержки SSL и TLS 2.0 (в значительной степени стандарт для большинства хостов с https), а не отключать его для загрузки http. Имена пользователей и пароли не должны переходить через http.

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

Добавьте это в свой файл info.plist (откройте его в режиме исходного кода, нажмите на файл и выберите)

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Если вы хотите контролировать определенные URL-адреса, вы можете использовать <key>NSExceptionDomains</key>

person some_id    schedule 20.10.2015
comment
Я уже добавил приведенный выше код в свой info.plist в начале. Потому что вначале это не работало в моем симуляторе, но после того, как я добавил код выше, он заработал, но только в моем симуляторе. Я проведу исследование, чтобы изменить мой домашний сервер для поддержки SSL. - person O.S.Kaya; 20.10.2015