Swift: ошибка при попытке связи с веб-API

Я пытаюсь создать действительно простое приложение для iOS с помощью Swift - я делаю это впервые. В то время как большинство из них было действительно прямолинейным. У меня был полный кошмар, чтобы заставить приложение общаться с моим API или любым сайтом в целом!

Это код, который я использую, и, в частности, код с ошибкой:

     NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{     (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
         println(NSString(data: data, encoding: NSUTF8StringEncoding))
     })

это «NSString (данные: данные, кодировка: NSUTF8StringEncoding)», что приводит к ошибкам

Я просмотрел столько руководств, сколько смог найти, и все они возвращают мне одну и ту же проблему. Я получаю сообщение об ошибке:

NSURLErrorDomain — код: 4294966291

Я также получаю ошибку «EXC_BAD_INSTRUCTION» с: EXC_1386_INVOP, sub code = 0x0 (что не привело меня к решению...

Это заставляет меня думать, что я сделал что-то не так в своей настройке, или что-то должно быть включено в моих настройках, или что-то в этом роде, в отличие от моего кода...

это весь мой код:

    var URL: NSURL = NSURL(string: "http://stackoverflow.com")

    var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
    request.HTTPMethod = "POST"

    var bodyData = "key1=value&key2=value&key3=value"

    println(URL)
    println(bodyData)

    request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        println(NSString(data: data, encoding: NSUTF8StringEncoding))
    })

Обновлять:

Используя код Роба, я знаю, что печатается ошибка:

Ошибка sendAsynchronousRequest: Error Domain = NSURLErrorDomain Code = -1005 «Сетевое соединение было потеряно». UserInfo=0x7beafcc0 {NSErrorFailingURLStringKey=http://stackoverflow.com, _kCFStreamErrorCodeKey=57, NSErrorFailingURLKey=http://stackoverflow.com, NSLocalizedDescription=Сетевое соединение было потеряно., _kCFStreamErrorDomainKey=1, NSUnderlyingError=0x7d154ca0 "Сетевое соединение было потеряно."}


person user2707631    schedule 08.10.2014    source источник
comment
Вы изменили URL-адрес перед публикацией этого? Вышеупомянутое работает для меня. Я всегда устанавливал Content-Type, например. request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type"), но я не думаю, что здесь проблема.   -  person Rob    schedule 08.10.2014
comment
Это буквально код, который у меня есть!   -  person user2707631    schedule 08.10.2014
comment
Затем я запустил это с помощью Charles и посмотрел, как выглядит ответ.   -  person Rob    schedule 08.10.2014
comment
Я также могу предложить попробовать другой URL-адрес (чтобы узнать, не связана ли проблема с ответом сервера Stack Overflow). Итог, кроме отсутствия обработки ошибок (которую вы, очевидно, теперь добавили) и отсутствия Content-Type, я не вижу никаких проблем с приведенным выше кодом. И трудно диагностировать, если мы не можем воспроизвести проблему.   -  person Rob    schedule 08.10.2014
comment
Хорошо, спасибо, Роб, за помощь!!   -  person user2707631    schedule 08.10.2014


Ответы (2)


Похоже, data это nil. Изучите содержимое объекта error, и вы поймете, почему. Скорее всего, что-то не так с request, но если мы не сможем воспроизвести проблему, ее трудно диагностировать.

В любом случае, если вы хотите выполнить запрос с немного большей диагностической информацией (запишите error, если есть проблема, запишите statusCode и response, если код состояния не равен 200 и т. д.):

NSURLConnection.sendAsynchronousRequest(request, queue: queue) {
    response, data, error in

    if data == nil {
        println("sendAsynchronousRequest error: \(error)")
        return
    }

    if let httpResponse = response as? NSHTTPURLResponse {
        let statusCode = httpResponse.statusCode
        if statusCode != 200 {
            println("sendAsynchronousRequest status code = \(statusCode); response = \(response)")
        }
    }

    println(NSString(data: data, encoding: NSUTF8StringEncoding))
}

В своем исправленном вопросе вы поделились полученным NSError, который сообщил -1005 (который, оглядываясь назад, совпадает с кодом ошибки 4294966291, который вы показали нам ранее; последний представляет собой целочисленное представление -1005 без знака). Эта ошибка (как указано в описании) предназначена для NSURLErrorNetworkConnectionLost (то есть kCFURLErrorNetworkConnectionLost), для которого в документации сказано: «Возвращается, когда соединение с клиентом или сервером разрывается в середине выполняемой загрузки».

К сожалению, эта ошибка используется для решения самых разных проблем, и, поскольку я не могу воспроизвести описанную вами ошибку, ее трудно диагностировать.


Одна вещь, которая отсутствует в запросе, это спецификация Content-Type:

request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

Это не вызовет проблемы, которую вы описываете, но рекомендуется всегда информировать сервер о типе запроса.

person Rob    schedule 08.10.2014
comment
Спасибо, Роб, я получаю: data = (NSData!) nil - это то, что вы имеете в виду? - person user2707631; 08.10.2014

Я решил это, отчасти благодаря ответам Роба и общей помощи - это было очень полезно.

В конце концов, ключ был очень простым и взят из этого вопроса: -lost">Error Domain=NSURLErrorDomain Code=-1005 Сетевое подключение было потеряно.

Мне просто пришлось перезапустить симулятор. Однако я бы не добился этого без дополнительного оператора if data == nil {}.

person user2707631    schedule 08.10.2014