swift http请求无法获得非200响应

时间:2016-03-23 14:13:27

标签: ios swift

我使用下面的swift代码来发出http请求。如果服务器响应200 OK响应,swift可以正常工作。但是,在服务器响应超过200状态时,completionHandler回调永远不会被调用,直到超时。 swift上还有其他设置可以防止接收其他状态响应吗?

let urlStr = "http://xxxxx"
let url = NSURL(string: urlStr)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "post"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {(data, response, error) in
    guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
                // no response code
        print("response")
        return
    }
    print("get response from register service \(data) \(error)")         
})
task.resume()

如果发生这种情况,我会收到以下超时错误:

  

获取登录响应nil错误:可选(错误域= NSURLErrorDomain代码= -1001"请求超时。" UserInfo = {NSErrorFailingURLStringKey = http://XXXXX,NSErrorFailingURLKey = http://localhost:8080/nurse/login ,_kCFStreamErrorDomainKey = 4,_kCFStreamErrorCodeKey = -2103,NSLocalizedDescription =请求超时。})

我也用curl命令测试了,我能够得到如下的响应。所以服务器端对我来说很好。我相信问题出在客户端。

$ curl -i -X POST -d 'mobile=1234' http://localhost:8080/nurse/login
HTTP/1.1 10029 
Server: Apache-Coyote/1.1
X-Application-Context: application
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: access_token
Content-Type: text/plain;charset=UTF-8
Content-Length: 18
Date: Thu, 24 Mar 2016 02:39:09 GMT

1 个答案:

答案 0 :(得分:0)

这似乎是服务器方面的问题。以下代码适用(在Playground中):

尝试使用此网址,看看是否发生了这种情况。

另外,在调试Swift代码之前,我会使用像curl这样的简单工具来手动测试服务器端:

curl -i -X POST -d 'name=yoyo' http://putsreq.com/vccZnwiNpP23RF7nwOPE

修改

这是一个可以完成你想要的功能。我硬编码了您的网址,现在情况正常。

func postSomeStuff(data: String, completion: (data: NSData?, error: NSError?)->Void) {

    let post: NSString = "data=\(data)"
    let url = NSURL(string: "http://123.56.184.207:8080/nurse/login")!
    let postData = post.dataUsingEncoding(NSUTF8StringEncoding)!

    let postLength = String(postData.length)

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("*/*", forHTTPHeaderField: "Accept")

    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    config.timeoutIntervalForRequest = 120
    config.timeoutIntervalForResource = 240

    let session = NSURLSession(configuration: config)

    let task = session.dataTaskWithRequest(request) { urlData, response, reponseError in

        if let receivedData = urlData {
            let res = response as! NSHTTPURLResponse!;

            NSLog("Response code: %ld", res.statusCode);

            if 200..<300 ~= res.statusCode {
                completion(data: receivedData, error: nil)
            } else {
                let returnedError = NSError(domain: "getSomeStuff", code: 1, userInfo: [:])
                completion(data: nil, error: returnedError)
            }
        } else {
            var userInfo: [NSObject: AnyObject] = [:]
            if let error = reponseError {
                userInfo["message"] = error.localizedDescription
                userInfo["cause"] = error
            }
            let returnedError = NSError(domain: "myFunc", code: 2, userInfo: userInfo)
            completion(data: nil, error: returnedError)
        }
    }
    task.resume()
}

postSomeStuff("yoyo") { data , err in
    if let data = data { print(data) }
    if let err = err { print(err) }
}

let sema = dispatch_semaphore_create(0);
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);


// Used only in Playground
XCPSetExecutionShouldContinueIndefinitely(true)