#1 楼
您可以像在Objective-C中通常使用的那样使用URL
,URLRequest
和URLSession
或NSURLConnection
。请注意,对于iOS 7.0和更高版本,首选URLSession
。使用
URLSession
从
URL
初始化URLSessionDataTask
对象和URLSession
。然后使用resume()
运行任务。let url = URL(string: "http://www.stackoverflow.com")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
使用
NSURLConnection
首先,初始化
URL
和URLRequest
:let url = URL(string: "http://www.stackoverflow.com")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
然后,您可以加载异步请求:
NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main) {(response, data, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
,或者您可以初始化
NSURLConnection
:let connection = NSURLConnection(request: request, delegate:nil, startImmediately: true)
只需确保将委托设置为
nil
以外的其他值,并使用委托方法与响应和收到的数据。有关详细信息,请查看
NSURLConnectionDataDelegate
协议的文档在Xcode操场上进行测试
如果要在Xcode操场上尝试此代码,请将
import PlaygroundSupport
添加到操场上,以及以下调用:PlaygroundPage.current.needsIndefiniteExecution = true
这将允许您在操场上使用异步代码。
评论
不要在操场上的iOS 8 beta 2上浪费时间,因为不支持XCPlayground。如果您想尝试黑客,有一种聪明而丑陋的方法可以等待:stackoverflow.com/a/24058337/700206
–惠特尼乐园
2014年7月1日在13:48
如何使用NSURLSession发送POST数据?
–费尔南多·圣地亚哥
2014年9月21日19:23在
此示例在6.1失败:test.swift:5:57:错误:可选类型'NSURL?'的值没有包装;你是说用'!'要么 '?'? let task = NSURLSession.sharedSession()。dataTaskWithURL(url){{data,response,error)in
– mcuadros
2014年10月12日12:04
添加感叹号可修复@mcuadros的错误消息... .dataTaskWithURL(url!)
– Sean McClory
14-10-30在15:04
您能修复代码片段吗?这是从Swift 4 print开始工作的内容(String(data:data !, encoding:String.Encoding.utf8))
–内特
17年7月2日在9:27
#2 楼
检查以下代码:1。 SynchonousRequest
Swift 1.2
let urlPath: String = "YOUR_URL_HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSURLRequest = NSURLRequest(URL: url)
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var dataVal: NSData = NSURLConnection.sendSynchronousRequest(request1, returningResponse: response, error:nil)!
var err: NSError
println(response)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary
println("Synchronous\(jsonResult)")
Swift 2.0 +
let urlPath: String = "YOUR_URL_HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSURLRequest = NSURLRequest(URL: url)
let response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
do{
let dataVal = try NSURLConnection.sendSynchronousRequest(request1, returningResponse: response)
print(response)
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
print("Synchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}catch let error as NSError
{
print(error.localizedDescription)
}
2。 AsynchonousRequest
Swift 1.2
let urlPath: String = "YOUR_URL_HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSURLRequest = NSURLRequest(URL: url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("Asynchronous\(jsonResult)")
})
Swift 2.0 +
let urlPath: String = "YOUR_URL_HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSURLRequest = NSURLRequest(URL: url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("ASynchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
})
3。和往常一样URL连接
Swift 1.2 2.0 +
var dataVal = NSMutableData()
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
connection.start()
然后
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.dataVal?.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!)
{
var error: NSErrorPointer=nil
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
println(jsonResult)
}
4。异步POST请求
Swift 1.2
var dataVal = NSMutableData()
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
connection.start()
Swift 2.0 +
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
dataVal.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!)
{
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
5,异步GET请求
Swift 1.2
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
var stringPost="deviceToken=123456" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request1.timeoutInterval = 60
request1.HTTPBody=data
request1.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("AsSynchronous\(jsonResult)")
})
Swift 2.0 +
let urlPath: String = "YOUR URL HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
let stringPost="deviceToken=123456" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request1.timeoutInterval = 60
request1.HTTPBody=data
request1.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("ASynchronous\(jsonResult)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
})
6。图片(文件)上传
Swift 2.0 +
let urlPath: String = "YOUR URL HERE"
var url: NSURL = NSURL(string: urlPath)!
var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "GET"
request1.timeoutInterval = 60
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("AsSynchronous\(jsonResult)")
})
#3 楼
另一个选项是Alamofire库,它提供可链接的请求/响应方法。https://github.com/Alamofire/Alamofire
发出请求
import Alamofire
Alamofire.request(.GET, "http://httpbin.org/get")
响应处理
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(error)
}
评论
我认为,尽管建议由外部lib提供答复,而框架提供的功能却不是正确的方法。
– turkishweb
16年2月2日,13:25
@turkishweb是正确的。 Cezar的答案更加完整,并且不使用外部库。那应该是公认的答案。
– fredmaggiowski
16年2月2日在13:28
Cezar的答案已经过时了(自Swift 3起),Alamofire的界面比URLSession和consorts的界面好很多。同样,接受并不是衡量某种善良程度的抽象标准(更不用说您了!!)),而是对OP的最大帮助。 (对于“纯”解决方案,有SO文档!)如果这是答案,那就完美了-它不是在使用第一手原则,但是那并不总是“正确”的解决方案,不是吗?
–拉斐尔
17 Mar 24 '17在45
除非特别要求,否则请不要提供第三方库(根据SO指南)
– Alec O
17年11月17日在3:23
@AlecO能否请我指出这些指南的内容?
–拉斐尔
19年3月19日在7:10
#4 楼
Swift 4及以上版本:使用URLSession API的数据请求 //create the url with NSURL
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! //change the url
//create the session object
let session = URLSession.shared
//now create the URLRequest object using the url object
let request = URLRequest(url: url)
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
Swift 4及以上版本,可解码和结果枚举
//APPError enum which shows all possible errors
enum APPError: Error {
case networkError(Error)
case dataNotFound
case jsonParsingError(Error)
case invalidStatusCode(Int)
}
//Result enum to show success or failure
enum Result<T> {
case success(T)
case failure(APPError)
}
//dataRequest which sends request to given URL and convert to Decodable Object
func dataRequest<T: Decodable>(with url: String, objectType: T.Type, completion: @escaping (Result<T>) -> Void) {
//create the url with NSURL
let dataURL = URL(string: url)! //change the url
//create the session object
let session = URLSession.shared
//now create the URLRequest object using the url object
let request = URLRequest(url: dataURL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil else {
completion(Result.failure(AppError.networkError(error!)))
return
}
guard let data = data else {
completion(Result.failure(APPError.dataNotFound))
return
}
do {
//create decodable object from data
let decodedObject = try JSONDecoder().decode(objectType.self, from: data)
completion(Result.success(decodedObject))
} catch let error {
completion(Result.failure(APPError.jsonParsingError(error as! DecodingError)))
}
})
task.resume()
}
示例:
///如果我们想从占位符API获取待办事项,那么我们定义ToDo结构并调用dataRequest并传递“ https://jsonplaceholder.typicode.com/todos/1 “字符串url。
struct ToDo: Decodable {
let id: Int
let userId: Int
let title: String
let completed: Bool
}
dataRequest(with: "https://jsonplaceholder.typicode.com/todos/1", objectType: ToDo.self) { (result: Result) in
switch result {
case .success(let object):
print(object)
case .failure(let error):
print(error)
}
}
//这将打印结果:
ToDo(id: 1, userId: 1, title: "delectus aut autem", completed: false)
评论
如何调整它以接受对象数组?
–kirqe
10月8日,19:15
@kirqe如果您想接受数组作为响应,则传递`objectType:[T] .self``,这里T确认为可解码协议
– Suhit Patil
10月8日,19:54
#5 楼
Swift 3+基本解决方案guard let url = URL(string: "http://www.stackoverflow.com") else { return }
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
print(NSString(data: data, encoding: String.Encoding.utf8.rawValue))
}
task.resume()
评论
您的示例适用于Swift 3,因此应使用URL(string:“ http://www.stackoverflow.com”)而不是NSURL
– FelixSFD
16年8月23日在11:29
从URL转换为URL没有意义URLSession.shared.dataTask(with:url!)
– Leo Dabus
16年2月2日在16:51
我收到此错误:应用传输安全性由于不安全,阻止了明文HTTP(http://)资源加载。可以通过应用程序的Info.plist文件配置临时异常。
–user285594
17年2月9日在17:26
@YumYumYum您是否已根据此文章stackoverflow.com/questions/30731785/…配置了应用程序传输安全性?
–本·沙利文(Ben Sullivan)
17-2-10在17:36
Leo Dabus变量url是URL类型吗?
–汤姆·舒尔茨(Tom Schulz)
18年4月16日在20:29
#6 楼
Swift 3.0通过一个小的抽象
https://github.com/daltoniam/swiftHTTP
示例
do {
let opt = try HTTP.GET("https://google.com")
opt.start { response in
if let err = response.error {
print("error: \(err.localizedDescription)")
return //also notify app of failure as needed
}
print("opt finished: \(response.description)")
//print("data is: \(response.data)") access the response of the data with response.data
}
} catch let error {
print("got an error creating the request: \(error)")
}
评论
您是否找到一种在显示视图之前等待请求完成的方法? @AlexanderN
–重塑
15年3月18日在21:56
#7 楼
详细信息Xcode 9.2,Swift 4
Xcode 10.2.1(10E1001),Swift 5
Info.plist
NSAppTransportSecurity
添加到信息列表:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Alamofire示例
Alamofire
import Alamofire
class AlamofireDataManager {
fileprivate let queue: DispatchQueue
init(queue: DispatchQueue) { self.queue = queue }
private func createError(message: String, code: Int) -> Error {
return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
}
private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((Result<[String: Any]>) -> Void)?) {
Alamofire.request(request).responseJSON { response in
let complete: (Result<[String: Any]>) ->() = { result in DispatchQueue.main.async { closure?(result) } }
switch response.result {
case .success(let value): complete(.success(value as! [String: Any]))
case .failure(let error): complete(.failure(error))
}
}
}
func searchRequest(term: String, closure: ((Result<[String: Any]>) -> Void)?) {
guard let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))") else { return }
let request = URLRequest(url: url)
make(request: request) { response in closure?(response) }
}
}
Alamofire示例的使用
private lazy var alamofireDataManager = AlamofireDataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
//.........
alamofireDataManager.searchRequest(term: "jack johnson") { result in
print(result.value ?? "no data")
print(result.error ?? "no error")
}
URLSession示例
import Foundation
class DataManager {
fileprivate let queue: DispatchQueue
init(queue: DispatchQueue) { self.queue = queue }
private func createError(message: String, code: Int) -> Error {
return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
}
private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
let task = session.dataTask(with: request) { [weak self] data, response, error in
self?.queue.async {
let complete: (_ json: [String: Any]?, _ error: Error?) ->() = { json, error in DispatchQueue.main.async { closure?(json, error) } }
guard let self = self, error == nil else { complete(nil, error); return }
guard let data = data else { complete(nil, self.createError(message: "No data", code: 999)); return }
do {
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
complete(json, nil)
}
} catch let error { complete(nil, error); return }
}
}
task.resume()
}
func searchRequest(term: String, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))")
let request = URLRequest(url: url!)
make(request: request) { json, error in closure?(json, error) }
}
}
URLSession示例的使用
private lazy var dataManager = DataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
// .......
dataManager.searchRequest(term: "jack johnson") { json, error in
print(error ?? "nil")
print(json ?? "nil")
print("Update views")
}
结果
评论
searchRequest?术语?他们来自哪里?
– El Tomato
18年1月22日在3:28
这是请求的完整样本。 class func searchRequest(term:String,...是从itunes.apple.com下载数据的示例。此示例将进行搜索,因此,我选择/发明了searchRequest函数名称。term是“ itunes.apple.com/搜索?”。您可以选择函数的任何名称来描述您的逻辑模型。
–瓦西里·博德纳丘克(Vasily Bodnarchuk)
18年1月22日在8:45
不错的解决方案。我已经更改了闭包以返回包含成功和错误案例的枚举。
–霓虹灯
18年4月11日在8:29
#8 楼
我已经完成了HTTP请求两种方法JSON的GET和POST解析,方法如下:on viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
makeGetRequest()
makePostRequest()
}
func makePostRequest(){
let urlPath: String = "http://www.swiftdeveloperblog.com/http-post-example-script/"
var url: NSURL = NSURL(string: urlPath)!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
var stringPost="firstName=James&lastName=Bond" // Key and Value
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request.timeoutInterval = 60
request.HTTPBody=data
request.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// Success
println(jsonResult)
let message = jsonResult["Message"] as! NSString
println(message)
}else {
// Failed
println("Failed")
}
})
}
func makeGetRequest(){
var url : String = "http://api.androidhive.info/contacts/"
var request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
request.timeoutInterval = 60
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if (jsonResult != nil) {
// Success
println(jsonResult)
let dataArray = jsonResult["contacts"] as! NSArray;
for item in dataArray { // loop through data items
let obj = item as! NSDictionary
for (key, value) in obj {
println("Key: \(key) - Value: \(value)")
let phone = obj["phone"] as! NSDictionary;
let mobile = phone["mobile"] as! NSString
println(mobile)
let home = phone["home"] as! NSString
println(home)
let office = phone["office"] as! NSString
println(office)
}
}
} else {
// Failed
println("Failed")
}
})
}
完成
评论
无法使用类型为'(NSMutableURLRequest,queue:NSOperationQueue,completeHandler:(NSURLResponse !, NSData !, NSError!)-> Void)'的参数列表调用'sendAsynchronousRequest'
– bMalum
15年8月17日在9:27
#9 楼
使用URLSession + Swift 5只需添加到cezar的答案中,如果您想使用Apple的URLSession类发出Web请求,则可以通过多种方式执行任务
使用URL的简单GET请求
带URL和参数的简单GET请求
带错误处理的URL的简单GET请求
带URL和错误处理的参数的简单POST请求
1。带有URL的简单GET请求
func simpleGetUrlRequest()
{
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print("The response is : ",String(data: data, encoding: .utf8)!)
//print(NSString(data: data, encoding: String.Encoding.utf8.rawValue) as Any)
}
task.resume()
}
注意:确保必须在pList中为http请求添加“ NSAppTransportSecurity”键
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2。具有URL和参数的简单GET请求。
func simpleGetUrlWithParamRequest()
{
let url = URL(string: "https://www.google.com/search?q=peace")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
print("The Response is : ",response)
}
task.resume()
}
3。具有URL并带有错误处理的简单GET请求。
func simpleGetUrlRequestWithErrorHandling()
{
let session = URLSession.shared
let url = URL(string: "https://httpbin.org/get")!
let task = session.dataTask(with: url) { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print("The Response is : ",json)
} catch {
print("JSON error: \(error.localizedDescription)")
}
}
task.resume()
}
4。带有URL的简单POST请求,带有错误处理的参数。
func simplePostRequestWithParamsAndErrorHandling(){
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
let session = URLSession(configuration: configuration)
let url = URL(string: "https://httpbin.org/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let parameters = ["username": "foo", "password": "123456"]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Oops!! there is server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("response is not json")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print("The Response is : ",json)
} catch {
print("JSON error: \(error.localizedDescription)")
}
})
task.resume()
}
您的建议受到赞赏!
评论
为什么不使用var session = URLSession.shared而不使用它,而只覆盖变量?需要吗?
–vrwim
19年8月7日在13:17
#10 楼
我在登录按钮click上调用json。
@IBAction func loginClicked(sender : AnyObject) {
var request = NSMutableURLRequest(URL: NSURL(string: kLoginURL)) // Here, kLogin contains the Login API.
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(self.criteriaDic(), options: nil, error: &err) // This Line fills the web service with required parameters.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
var err1: NSError?
var json2 = NSJSONSerialization.JSONObjectWithData(strData.dataUsingEncoding(NSUTF8StringEncoding), options: .MutableLeaves, error:&err1 ) as NSDictionary
println("json2 :\(json2)")
if(err) {
println(err!.localizedDescription)
}
else {
var success = json2["success"] as? Int
println("Success: \(success)")
}
})
task.resume()
}
这里,我为参数制作了单独的字典。
var params = ["format":"json", "MobileType":"IOS","MIN":"f8d16d98ad12acdbbe1de647414495ec","UserName":emailTxtField.text,"PWD":passwordTxtField.text,"SigninVia":"SH"]as NSDictionary
return params
}
// You can add your own sets of parameter here.
#11 楼
您可以使用python-requests
样式的HTTP库Just。使用Just发送HTTP请求的一些示例:
// synchronous GET request with URL query a=1
let r = Just.get("https://httpbin.org/get", params:["a":1])
// asynchronous POST request with form value and file uploads
Just.post(
"http://justiceleauge.org/member/register",
data: ["username": "barryallen", "password":"ReverseF1ashSucks"],
files: ["profile_photo": .URL(fileURLWithPath:"flash.jpeg", nil)]
) { (r)
if (r.ok) { /* success! */ }
}
请求结果
r
的访问方式类似于python-request
:r.ok // is the response successful?
r.statusCode // status code of response
r.content // response body as NSData?
r.text // response body as text?
r.json // response body parsed by NSJSONSerielization
您可以在此游乐场找到更多示例
使用该库在操场上以同步模式运行是最接近cURL的东西,可以在Swift中获得。
评论
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。
– dimo414
15年5月13日在21:51
似乎已弃用该库。没有Swift 4支持,也没有人响应未解决的问题。
– Heinrisch
18/09/19在17:21
#12 楼
在Swift 4.1和Xcode 9.4.1中。JSON POST方法示例。要检查Internet连接,请从https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324-Intro-DontLinkElementID_2添加Reachability.h和.m文件
func yourFunctionName {
//Check internet connection
let networkReachability = Reachability.forInternetConnection()
let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
print(networkStatus)
if networkStatus == NotReachable.rawValue {
let msg = SharedClass.sharedInstance.noNetMsg//Message
//Call alert from shared class
SharedClass.sharedInstance.alert(view: self, title: "", message: msg)
} else {
//Call spinner from shared class
SharedClass.sharedInstance.activityIndicator(view: self.view)//Play spinner
let parameters = "Your parameters here"
var request = URLRequest(url: URL(string: url)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
//Stop spinner
SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
//Print error in alert
SharedClass.sharedInstance.alert(view: self, title: "", message: "\(String(describing: error!.localizedDescription))")
return
}
SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject]
print(response!)
//Your code here
} catch let error as NSError {
print(error)
}
}
task.resume()
}
}
如果您有兴趣在SharedClass中使用此功能
//My shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()
func postRequestFunction(apiName: String , parameters: String, onCompletion: @escaping (_ success: Bool, _ error: Error?, _ result: [String: Any]?)->()) {
var URL = "your URL here/index.php/***?"
URL = URL.replacingOccurrences(of: "***", with: apiName)
var request = URLRequest(url: URL(string: URL)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
print("shared URL : \(request)")
request.httpBody = parameters.data(using: .utf8)
var returnRes:[String:Any] = [:]
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
onCompletion(false, error, nil)
} else {
guard let data = data else {
onCompletion(false, error, nil)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 200 {
do {
returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
onCompletion(true, nil, returnRes)
} catch let error as NSError {
onCompletion(false, error, nil)
}
} else {
onCompletion(false, error, nil)
}
}
}
task.resume()
}
private override init() {
}
最后调用此函数这个....
SharedClass.sharedInstance.postRequestFunction(apiName: "Your API name", parameters: parameters) { (success, error, result) in
print(result!)
if success {
//Your code here
} else {
print(error?.localizedDescription ?? "")
}
}
#13 楼
发出HTTP GET请求的简单Swift 2.0方法HTTP请求是异步的,因此您需要一种从HTTP请求获取返回值的方法。此方法使用通告程序,并且分布在两个类中。
示例是使用网站http://www.example.com/handler.php?do=CheckUserJson&json=来检查标识符令牌的用户名和密码,该文件称为处理程序。 php并在do参数上具有switch语句以获得RESTful方法。
在viewDidLoad中,我们设置了NotifierObserver,设置了json并调用了getHTTPRequest函数。它将返回带有http请求返回的参数的函数checkedUsernameAndPassword。进行HTTP调用。
override func viewDidLoad() {
super.viewDidLoad()
// setup the Notification observer to catch the result of check username and password
NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkedUsernameAndPassword:", name: CHECK_USERNAME_AND_PASSWORD, object: nil)
let username = GlobalVariables.USER_NAME
let password = GlobalVariables.PASSWORD
// check username and password
if let jsonString = Utility.checkUsernameAndPasswordJson(username, password:password){
print("json string returned = \(jsonString)")
let url = CHECKUSERJSON+jsonString
// CHECKUSERJSON = http://www.example.com/handler.php?do=CheckUserJson&json=
// jsonString = {\"username\":\"demo\",\"password\":\"demo\"}"
// the php script handles a json request and returns a string identifier
Utility.getHTTPRequest(url,notifierId: CHECK_USERNAME_AND_PASSWORD)
// the returned identifier is sent to the checkedUsernaeAndPassword function when it becomes availabel.
}
}
和Http请求
static func checkUsernameAndPasswordJson(username: String, password: String) -> String?{
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue("demo", forKey: "username")
para.setValue("demo", forKey: "password")
let jsonData: NSData
do{
jsonData = try NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
return jsonString
} catch _ {
print ("UH OOO")
return nil
}
}
sendNotification函数完善了圈子。注意,在Observer中,选择器字符串的末尾有一个“:”。这允许通知在userInfo中携带有效负载。我给它一个字符串和一个整数。
static func getHTTPRequest (url:String , notifierId: String) -> Void{
let urlString = url
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
let safeURL = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
if let url = NSURL(string: safeURL){
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.timeoutInterval = 60
let taskData = session.dataTaskWithRequest(request, completionHandler: {
(data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
if (data != nil) {
let result = NSString(data: data! , encoding: NSUTF8StringEncoding)
sendNotification (notifierId, message: String(result), num: 0)
}else{
sendNotification (notifierId, message: String(UTF8String: nil), num: -1) }
})
taskData.resume()
}else{
print("bad urlString = \(urlString)")
}
}
请注意,使用HTTP已过时,更喜欢使用HTTPS,请参阅如何在iOS中启用应用传输安全性的情况下加载HTTP URL 9?
#14 楼
var post:NSString = "api=myposts&userid=\(uid)&page_no=0&limit_no=10"
NSLog("PostData: %@",post);
var url1:NSURL = NSURL(string: url)!
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
var postLength:NSString = String( postData.length )
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url1)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
if ( urlData != nil ) {
let res = response as NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
var responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %@", responseData);
var error: NSError?
let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary
let success:NSInteger = jsonData.valueForKey("error") as NSInteger
//[jsonData[@"success"] integerValue];
NSLog("Success: %ld", success);
if(success == 0)
{
NSLog("Login SUCCESS");
self.dataArr = jsonData.valueForKey("data") as NSMutableArray
self.table.reloadData()
} else {
NSLog("Login failed1");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
} else {
NSLog("Login failed2");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
} else {
NSLog("Login failed3");
ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}
肯定会为您提供帮助
#15 楼
//这是为我工作的示例// Swift函数将具有键值的请求发布到服务器
func insertRecords()
{
let usrID = txtID.text
let checkin = lblInOut.text
let comment = txtComment.text
// The address of the web service
let urlString = "http://your_url/checkInOut_post.php"
// These are the keys that your are sending as part of the post request
let keyValues = "id=\(usrID)&inout=\(checkin)&comment=\(comment)"
// 1 - Create the session by getting the configuration and then
// creating the session
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
// 2 - Create the URL Object
if let url = NSURL(string: urlString){
// 3 - Create the Request Object
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// set the key values
request.HTTPBody = keyValues.dataUsingEncoding(NSUTF8StringEncoding);
// 4 - execute the request
let taskData = session.dataTaskWithRequest(request, completionHandler: {
(data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
println("\(data)")
// 5 - Do something with the Data back
if (data != nil) {
// we got some data back
println("\(data)")
let result = NSString(data: data , encoding: NSUTF8StringEncoding)
println("\(result)")
if result == "OK" {
let a = UIAlertView(title: "OK", message: "Attendece has been recorded", delegate: nil, cancelButtonTitle: "OK")
println("\(result)")
dispatch_async(dispatch_get_main_queue()) {
a.show()
}
} else {
// display error and do something else
}
} else
{ // we got an error
println("Error getting stores :\(error.localizedDescription)")
}
})
taskData.resume()
}
}
PHP获取键值的代码
$ empID = $ _POST ['id'];
$ inOut = $ _POST ['inout'];
$ comment = $ _POST ['comment'];
#16 楼
这是一个在操场上非常简单的Swift 4示例:import UIKit
// run asynchronously in a playground
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// create a url
let url = URL(string: "http://www.stackoverflow.com")
// create a data task
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("there's a problem")
}
print(String(data: data!, encoding: String.Encoding.utf8) ?? "")
}
//running the task w/ resume
task.resume()
#17 楼
为了使XCUITest在异步请求完成之前停止测试完成,请使用此命令(可能减少100超时):func test_api() {
let url = URL(string: "https://jsonplaceholder.typicode.com/posts/42")!
let exp = expectation(description: "Waiting for data")
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
exp.fulfill()
}
task.resume()
XCTWaiter.wait(for: [exp], timeout: 100)
}
#18 楼
吻答案:URLSession.shared.dataTask(with: URL(string: "https://google.com")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8))
}.resume()
#19 楼
发出HTTP请求是现代语言的核心功能,并且是许多开发人员在适应新环境时首先要学习的内容之一。在谈到Swift时,无论是语言本身还是社区内部,都为该问题提供了大量解决方案。让我们看一些最受欢迎的例子。这是Alamofire请求示例:-
在以下所有示例中,我们将在命令行上使用Swift。这并不意味着您不能将其中的任何一个复制并粘贴到Xcode,而是Swift拥有一系列有用的命令行实用程序,这些实用程序使在本教程中测试代码变得容易。
通过打开终端和导航到您希望此代码存在的目录。我的目录名为SwiftHTTP,您将在本文的其余示例中看到。
输入以下内容以生成可执行的命令行项目:
swift package init --type executable
这还将生成一个Package .swift文件。这样,我们可以添加依赖项以使用Swift Package Manager安装第三方库。
带有URLRequest的HTTP请求
首先,我们将使用称为URLRequest的内置API。如果要继续使用命令行,请在上一个命令生成的Sources目录中打开main.swift,然后输入以下代码:
import Foundation
// Set the URL the request is being made to.
let request = URLRequest(url: NSURL(string: "https://api.nasa.gov/planetary/apod?
api_key=DEMO_KEY")! as URL)
do {
// Perform the request
var response: AutoreleasingUnsafeMutablePointer<URLResponse?>? = nil
let data = try NSURLConnection.sendSynchronousRequest(request, returning: response)
// Convert the data to JSON
let jsonSerialized = try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
if let json = jsonSerialized, let url = json["url"], let explanation = json["explanation"] {
print(url)
print(explanation)
}
}
发出HTTP请求。回到您的终端并运行以下命令,请记住,您可能必须修改此命令以适合您的Swift项目的名称:
swift build && .build/debug/SwiftHTTP
带有URLSession的HTTP请求
URLSession是另一个发送内置于该语言的HTTP请求的流行方法。 URLSession也不执行主线程之外的请求,这很漂亮。
修改main.swift使其包含以下代码:
import Foundation
let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if let data = data {
do {
// Convert the data to JSON
let jsonSerialized = try JSONSerialization.jsonObject(with: data, options:
[]) as? [String : Any]
if let json = jsonSerialized, let url = json["url"], let explanation =
json["explanation"] {
print(url)
print(explanation)
}
} catch let error as NSError {
print(error.localizedDescription)
}
} else if let error = error {
print(error.localizedDescription)
}
}
task.resume()
// Infinitely run the main loop to wait for our request.
// Only necessary if you are testing in the command line.
RunLoop.main.run()
我们之前在URLRequest上使用的示例是同步的,但此示例是异步的。因此,我们在最后调用RunLoop.main.run()以确保脚本在响应请求之前没有完成执行。如果在不同的上下文中使用此代码,请随意删除最后一行。
和以前一样,运行以下代码:
swift build && .build/debug/SwiftHTTP
一旦获得响应,请使用以下命令杀死脚本ctrl-c。
使用Alamofire的HTTP请求
以前的方法已内置到该语言中。但是Swift中也有第三方网络库。 Alamofire在Swift社区中是一个出色的(也是最受欢迎的)。
Alamofire是一个用户友好且用途广泛的库,具有很多选择。它具有可链接的请求和响应方法,并处理样板功能,例如验证HTTP响应。
与其他示例不同,我们需要修改Package.swift使其起作用。我们还将使用另一个名为SwiftyJSON的库,该库使JSON的解析更加用户友好,并且可以与Alamofire很好地配合。 />现在回到main.swift更改代码以使用Alamofire:
import PackageDescription
let package = Package(
name: "SwiftHTTP",
dependencies: [
.Package(url: "https://github.com/Alamofire/Alamofire.git", majorVersion: 4),
.Package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", majorVersion: 3,
minor: 1)
]
)
就像我们前面的选项一样,请求是异步的,因此我们调用RunLoop.main。 run()。
#20 楼
下面给出了示例“ GET”请求的示例。let urlString = "YOUR_GET_URL"
let yourURL = URL(string: urlstring)
let dataTask = URLSession.shared.dataTask(with: yourURL) { (data, response, error) in
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
print("json --- \(json)")
}catch let err {
print("err---\(err.localizedDescription)")
}
}
dataTask.resume()
评论
使用URLSession(GET,POST,DELETE方法):stackoverflow.com/a/48306950/6898523