我在iBooks上读了苹果的编程语言Swift,但不知道如何在Swift中发出HTTP请求(类似cURL)。我需要导入Obj-C类还是只需要导入默认库?或者不能基于原生Swift代码进行HTTP请求?
当前回答
你可以使用URL URLRequest URLSession或者NSURLConnection就像你在Objective-C中通常做的那样。注意,对于iOS 7.0及更高版本,URLSession是首选。
使用URLSession
初始化URL对象和URLSession中的URLSessionDataTask。然后使用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
这将允许你在操场上使用异步代码。
其他回答
下面给出了一个“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()
基本的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()
下面是在Linux上使用Swift进行HTTP请求的从头到尾的说明。
首先创建一个SwiftPM包
mkdir swift-http && cd swift-http && swift package init --type executable
然后替换。/Sources/swift-http/main.swift 代码如下:
import Foundation
import FoundationNetworking
let sema = DispatchSemaphore(value: 0)
URLSession.shared.dataTask(with: URL(string: "http://numbersapi.com/42")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8) ?? String(describing: error))
sema.signal()
}.resume()
sema.wait()
然后运行代码
swift run
输出的例子:
[6/6] Build complete!
42 is the answer to the Ultimate Question of Life, the Universe, and Everything.
注意:使用DispatchSemaphore是为了使程序在得到响应之前不会退出。
你也可以这样做:
import Foundation
import FoundationNetworking
var done = false
URLSession.shared.dataTask(with: URL(string: "http://numbersapi.com/42")!) {(data, response, error) in
print(String(data: data!, encoding: .utf8) ?? String(describing: error))
done = true
}.resume()
while !done { Thread.sleep(forTimeInterval: 1) }
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")
}
它一定会对你有帮助
为了让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)
}
推荐文章
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- 如何舍入一个双到最近的Int在迅速?
- 扁平化数组的数组在Swift
- Swift:声明一个空字典
- 为什么ARC仍然需要@autoreleasepool ?
- 在成功提交我的应用程序后,“太多符号文件”
- 从数组中随机选择一个元素
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- Xcode 4挂在“附加到(应用程序名称)”
- CFNetwork SSLHandshake iOS 9失败