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(data: data, encoding: NSUTF8StringEncoding)'
Я прошел столько учебников, сколько смог найти, и все они возвращают мне одну и ту же проблему. Я получаю сообщение об ошибке:
NSURLErrorDomain - код: 4294966291
Я также получаю ошибку 'EXC_BAD_INSTRUCTION' с: EXC_1386_INVOP, субкод = 0x0 (что не привело меня к решению...
Это заставляет меня думать, что я что-то не так сделал правильно, или что-то должно быть включено в мои предпочтения, или что-то в этом роде, а не мой код...
это весь мой код:
var URL: NSURL = NSURL(string: "http://stackru.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: Ошибка Domain=NSURLErrorDomain Code=-1005 "Сетевое соединение потеряно". UserInfo = 0x7beafcc0 {NSErrorFailingURLStringKey = http://stackru.com/, _kCFStreamErrorCodeKey = 57, NSErrorFailingURLKey = http://stackru.com/, NSLocalizedDescription= Сетевое соединение было потеряно., _KCFStreamErrordror0 ".}
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")
Это не приведет к описанной вами проблеме, но рекомендуется всегда информировать сервер о типе запроса.
Я решил это, частично благодаря ответам Роба и общей помощи - это было очень полезно.
Ключ, в конце концов, был очень прост и взят из этого вопроса: Error Domain = NSURLErrorDomain Code = -1005 "Сетевое соединение было потеряно".
Мне просто пришлось перезапустить симулятор. Однако я бы не попал туда без дополнительного оператора if data == nil {}.