Я прочитал "Язык программирования Swift" Apple в iBooks, но не могу понять, как сделать запрос HTTP (что-то вроде CURL) в Swift. Нужно ли мне импортировать классы Obj-C или мне просто нужно импортировать библиотеки по умолчанию? Или невозможно сделать HTTP-запрос на основе собственного быстрого кода?
Как сделать запрос HTTP в Swift?
Ответ 1
Вы можете использовать URL
, URLRequest
и URLSession
или NSURLConnection
как это обычно NSURLConnection
в Objective-C. Обратите внимание, что для 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
Это позволит вам использовать асинхронный код на игровых площадках.
Ответ 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
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)
}
Swift 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!){
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)
}
}
4. Асинхронный запрос POST
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)
}
})
5. Asynchonous GET Request
Swift 1.2
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)")
})
Swift 2.0 +
let urlPath: String = "YOUR URL HERE"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "GET"
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 mainURL = "YOUR_URL_HERE"
let url = NSURL(string: mainURL)
let request = NSMutableURLRequest(URL: url!)
let boundary = "78876565564454554547676"
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST" // POST OR PUT What you want
let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let imageData = UIImageJPEGRepresentation(UIImage(named: "Test.jpeg")!, 1)
var body = NSMutableData()
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
// Append your parameters
body.appendData("Content-Disposition: form-data; name=\"name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("PREMKUMAR\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"description\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("IOS_DEVELOPER\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
// Append your Image/File Data
var imageNameval = "HELLO.jpg"
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"profile_photo\"; filename=\"\(imageNameval)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
//handle error
}
else {
let outputString : NSString = NSString(data:data!, encoding:NSUTF8StringEncoding)!
print("Response:\(outputString)")
}
}
dataTask.resume()
Ответ 3
Другим вариантом является lib Alamofire, который предлагает методы Chainable Request/Response.
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)
}
Ответ 4
Swift 3 и Swift 4: запрос данных с использованием API URLSession
//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, enodable и Resum enum
//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)
Ответ 5
Основное решение Swift 3
let url = URL(string: "http://www.stackoverflow.com")
let task = URLSession.shared.dataTask(with: url! as URL) { data, response, error in
guard let data = data, error == nil else { return }
print(NSString(data: data, encoding: String.Encoding.utf8.rawValue))
}
task.resume()
Ответ 6
Я использую эту упаковку с хорошими результатами до сих пор 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)")
}
Ответ 7
подробности
- Xcode 9.2, Swift 4
- Xcode 10.2.1 (10E1001), Swift 5
Info.plist
Добавьте к информационному листу:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Образец Аламофира
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")
}
Результаты
Ответ 8
Я сделал HTTP Request Оба метода GET и POST с помощью JSON Parsing. > следующим образом:
в 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")
}
})
}
Готово
Ответ 9
Я вызываю 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.
Ответ 10
Вы можете использовать Just, HTTP-библиотеку стиля python-requests
.
Пример отправки HTTP-запроса с помощью Just:
// 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.
Ответ 11
В Swift 4.1 и Xcode 9.4.1.
Пример подхода JSON POST. Чтобы проверить подключение к Интернету, добавьте файлы Reachability.h &.m из https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324-Intro-DontLinkElementID_2
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 ?? "")
}
}
Ответ 12
Простой подход Swift 2.0 к выполнению запроса HTTP GET
HTTP-запрос является асинхронным, поэтому вам нужен способ получить возвращаемое значение из HTTP-запроса. Этот подход использует Notifiers и распространяется на два класса.
Пример: проверить имя пользователя и пароль для токена идентификатора с помощью веб-сайта http://www.example.com/handler.php?do=CheckUserJson&json=. Это файл называется обработчиком. php и имеет оператор switch для параметра do, чтобы получить подход 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 скрипт 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 - oldFashioned, предпочитайте HTTPS см. Как загрузить URL-адрес HTTP с защитой транспорта приложений, включенной в iOS 9?
Ответ 13
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")
}
это поможет вам, конечно,
Ответ 14
//Вот пример, который работал у меня
//Функция 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'];
Ответ 15
Вот очень простой пример 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 a problem")
}
print(String(data: data!, encoding: String.Encoding.utf8) ?? "")
}
//running the task w/ resume
task.resume()
Ответ 16
Использование URLSession + Swift 5
Просто добавьте к cezar answer, если вы хотите сделать веб-запрос с использованием класса Apple URLSession, есть несколько способов выполнить задачу
- Простой запрос GET с URL
- Простой запрос GET с URL и параметрами
- Простой запрос GET с URL-адресом с обработкой ошибок
- Простой запрос POST с URL, параметры с обработкой ошибок
1. Простой запрос GET с URL
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()
}
.Примечание. Убедитесь, что вы должны добавить ключ "NSAppTransportSecurity" в pList для http запросов
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2. Простой запрос GET с URL и параметрами
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. Простой запрос GET с URL с обработкой ошибок
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. Простой запрос POST с URL, параметры с обработкой ошибок.
func simplePostRequestWithParamsAndErrorHandling(){
var session = URLSession.shared
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
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()
}
Ваши предложения приветствуются!
Ответ 17
Пример для примера запроса "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()
Ответ 18
Swift 5
Никто не упоминал об использовании конструктора загрузки URL Data(contentsOf:)
:
private func loadDataIntoUI(from url: URL) {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
if let data = try? Data(contentsOf: url) {
DispatchQueue.main.async {
// TODO: Update UI with data
}
}
}
}