我在iBooks上读了苹果的编程语言Swift,但不知道如何在Swift中发出HTTP请求(类似cURL)。我需要导入Obj-C类还是只需要导入默认库?或者不能基于原生Swift代码进行HTTP请求?
当前回答
一个简单的Swift 2.0方法来发出HTTP GET请求
HTTP请求是异步的,因此需要一种方法从HTTP请求中获取返回值。这种方法使用通知器,分布在两个类中。
示例是使用网站http://www.example.com/handler.php?do=CheckUserJson&json=检查标识符令牌的用户名和密码,该文件名为handler.php,并且在do参数上有一个switch语句以获得RESTful方法。
在viewDidLoad中,我们设置了NotifierObserver,设置了json,并调用getHTTPRequest函数。它将返回函数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.
}
}
在Utility.swift中有两个静态函数,首先用于编码json,然后执行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
}
}
和Http请求
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)")
}
}
sendNotification函数完成了循环。注意,在观察者中,在选择器字符串的末尾有一个“:”。这允许通知在userInfo中携带有效负载。我给它一个String和Int。
static func sendNotification (key: String, message:String?, num: Int?){
NSNotificationCenter.defaultCenter().postNotificationName(
key,
object: nil,
userInfo: (["message": message!,
"num": "\(num!)"])
)
}
注意,使用HTTP是老式的,更喜欢HTTPS见我如何加载一个HTTP URL与应用程序传输安全启用在iOS 9?
其他回答
你可以使用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
这将允许你在操场上使用异步代码。
斯威夫特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)")
}
一个简单的Swift 2.0方法来发出HTTP GET请求
HTTP请求是异步的,因此需要一种方法从HTTP请求中获取返回值。这种方法使用通知器,分布在两个类中。
示例是使用网站http://www.example.com/handler.php?do=CheckUserJson&json=检查标识符令牌的用户名和密码,该文件名为handler.php,并且在do参数上有一个switch语句以获得RESTful方法。
在viewDidLoad中,我们设置了NotifierObserver,设置了json,并调用getHTTPRequest函数。它将返回函数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.
}
}
在Utility.swift中有两个静态函数,首先用于编码json,然后执行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
}
}
和Http请求
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)")
}
}
sendNotification函数完成了循环。注意,在观察者中,在选择器字符串的末尾有一个“:”。这允许通知在userInfo中携带有效负载。我给它一个String和Int。
static func sendNotification (key: String, message:String?, num: Int?){
NSNotificationCenter.defaultCenter().postNotificationName(
key,
object: nil,
userInfo: (["message": message!,
"num": "\(num!)"])
)
}
注意,使用HTTP是老式的,更喜欢HTTPS见我如何加载一个HTTP URL与应用程序传输安全启用在iOS 9?
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")
}
它一定会对你有帮助
我已经完成了HTTP请求两种方法GET和POST与JSON解析的方式:
在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")
}
})
}
Done
推荐文章
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- Xcode 4挂在“附加到(应用程序名称)”
- CFNetwork SSLHandshake iOS 9失败
- swift语言中的结构与类
- 我如何在Swift连接字符串?
- 请求失败:不可接受的内容类型:文本/html使用AFNetworking 2.0
- 缺少推荐的图标文件-该包不包含iPhone / iPod Touch的应用程序图标,像素为“120x120”,png格式
- 以编程方式创建segue
- 在Objective-C中@synchronized如何锁定/解锁?
- 什么是HTTP“主机”报头?
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- Xcode构建失败“架构x86_64未定义的符号”
- 如何使用Xcode创建。ipa文件?
- 动态改变UILabel的字体大小