ios - swift 3 : URLSession/URLRequest Not Working

标签 ios swift swift3 nsurlsession nsurlrequest

我仍在尝试将我们的应用程序从 Swift 2 转换到 Swift 3,因为我被迫这样做,因为我们所有的 Apple 设备现在都运行 iOS 10。

我已经完成了代码转换并认为我做得很好,但是,在尝试调试我的 JSON 问题时(发布在另一个问题中),我现在正在处理甚至没有发送的请求。

let params: [String:AnyObject] = [
    "email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
    "action":"601" as AnyObject,
    "params":params as AnyObject
]

do {
    let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
    var request = URLRequest(url: URL(string: "http://domain.tld/path/")!)

    request.httpBody = requestObject
    request.httpMethod = "POST"

    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    NSLog("Got here?")

    session.dataTask(with: request) {data, response, error in
        guard let data = data, error == nil else {
            print("error=\(error)")
            return
        }

        NSLog("Got here 3?")

        let object:JSON = JSON(data:data)

        NSLog("Object: \(object)")
    }.resume()

    NSLog("Got here 4?")
} catch {
    NSLog("Got here catch?")
}

NSLog("End of getUser")

上面的代码产生以下输出:

2016-10-04 13:00:12.011969 OneTouch[1589:623015] [DYMTLInitPlatform] platform initialization successful
2016-10-04 13:00:12.264319 OneTouch[1589:622954] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2016-10-04 13:00:12.265321 OneTouch[1589:622954] [MC] Reading from public effective user settings.
2016-10-04 13:00:12.295055 OneTouch[1589:622954] Got here?
2016-10-04 13:00:12.295445 OneTouch[1589:622954] Got here 4?
2016-10-04 13:00:12.295515 OneTouch[1589:622954] End of getUser
(lldb) 

这意味着甚至没有发出请求。有没有我必须再次添加到 PLIST 的 key ?这开始变得烦人了。

下面是我的旧代码,它甚至不再工作了:

let params: [String:AnyObject] = [
    "email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
    "action":"601" as AnyObject,
    "params":params as AnyObject
]

do {
    let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
    let request = NSMutableURLRequest(url: URL(string: "http://domain.tld/path/" as String)!, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)

    request.httpBody = requestObject
    request.httpMethod = "POST"

    NSLog("Got here?")

    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
        if error != nil {
            NSLog("Got here 2?")
        }

        NSLog("Got here 3?")

        let object:JSON = JSON(data:data!)

        NSLog("Object: \(object)")
    })

    NSLog("Got here 4?")

    task.resume()
} catch {
    NSLog("Got here catch?")
}

NSLog("End of getUser")

上面的代码产生与其他代码相同的输出!

最佳答案

如果您在调用 getUser 后立即设置断点,URLSession 任务的完成处理程序将异步运行(即通常稍后完成,除非请求立即失败或得到满足通过一些缓存的响应)可能没有机会被调用。

如果您在 dataTask 完成处理程序中放置一个断点,您应该会在该点看到您的数据。


就个人而言,我会确保为 getUser 提供一个完成处理程序,以便您知道它何时完成:

func getUser(completionHandler: @escaping (JSON?, Error?) -> Void) {
    let params = [
        "email":"\(preferences.string(forKey: "preference_email")!)"
    ]

    let requestParams: [String: Any] = [
        "action": "601",
        "params": params
    ]

    do {
        let requestObject = try JSONSerialization.data(withJSONObject: requestParams)

        var request = URLRequest(url: URL(string: "http://domain.tld/path/")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 20)

        request.httpBody = requestObject
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")

        let task = URLSession.shared.dataTask(with: request) {data, response, error in
            guard let data = data, error == nil else {
                completionHandler(nil, error)
                return
            }

            completionHandler(JSON(data: data), nil)
        }

        task.resume()
    } catch {
        completionHandler(nil, error)
    }
}

然后当你调用它时,你可以这样做:

getUser { json, error in
    guard let json = json else {
        print(error)
        return
    }

    // do something with json
    print(json)
}

只需将断点放在getUser 的完成处理程序中。请记住,您无法保证完成处理程序是否会在主队列上运行,因此您需要确保将 UI 或模型更新分派(dispatch)回主队列。

关于ios - swift 3 : URLSession/URLRequest Not Working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860879/

相关文章:

ios - 具有许多图像的 UIScrollView 性能不佳

ios - NSSortDescriptor 不按字母顺序排序

arrays - 如何在 swift 3 中将带有自定义类的数组转换为 JSON

swift - 如何在 UILabel 文本中添加空白

ios - Swift 3 "didFinishPickingMediaWithInfo"用于 tableview 单元格内的图像

ios - Swift 3 和 JSON——通过在后台运行 URL 来更新数据库

iOS 应用程序仅在 TestFlight 构建时崩溃

ios - 如何删除 UITableViewCell 滑动以删除弹跳

ios - 以升序方式订购媒体 QBImagePickerController

ios - 无法通过按下 UIView xib 上的按钮显示表格 View