Ich habe "Die Programmiersprache Swift" von Apple in iBooks gelesen, kann aber nicht herausfinden, wie man in Swift eine HTTP-Anfrage (etwas ähnliches wie cURL) erstellt. Muss ich Obj-C-Klassen importieren oder reicht es aus, Standardbibliotheken zu importieren? Oder ist es nicht möglich, basierend auf nativem Swift-Code eine HTTP-Anfrage zu erstellen?
Antworten
Zu viele Anzeigen?In Swift 4.1 und Xcode 9.4.1.
JSON POST-Ansatzbeispiel. Um die Internetverbindung zu überprüfen, fügen Sie die Dateien Reachability.h & .m von https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324-Intro-DontLinkElementID_2 hinzu
func yourFunctionName {
//Internetverbindung überprüfen
let networkReachability = Reachability.forInternetConnection()
let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
print(networkStatus)
if networkStatus == NotReachable.rawValue {
let msg = SharedClass.sharedInstance.noNetMsg//Nachricht
//Alarm aus gemeinsamer Klasse aufrufen
SharedClass.sharedInstance.alert(view: self, title: "", message: msg)
} else {
//Ladesymbol aus gemeinsamer Klasse aufrufen
SharedClass.sharedInstance.activityIndicator(view: self.view)//Ladesymbol starten
let parameters = "Ihre Parameter hier"
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 { // grundlegenden Netzwerkfehler überprüfen
//Ladesymbol stoppen
SharedClass.sharedInstance.stopActivityIndicator() //Ladesymbol stoppen
//Fehler in Alarm ausgeben
SharedClass.sharedInstance.alert(view: self, title: "", message: "\(String(describing: error!.localizedDescription))")
return
}
SharedClass.sharedInstance.stopActivityIndicator() //Ladesymbol stoppen
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // http-Fehler überprüfen
print("statusCode sollte 200 sein, ist jedoch \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject]
print(response!)
//Ihr Code hier
} catch let error as NSError {
print(error)
}
}
task.resume()
}
}
Wenn Sie daran interessiert sind, diese Funktion in der SharedClass zu verwenden
//Meine gemeinsame Klasse
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 = "Ihre URL hier/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("geteilte 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() {
}
Und rufen Sie diese Funktion schließlich so auf....
SharedClass.sharedInstance.postRequestFunction(apiName: "Ihr API-Name", parameters: parameters) { (success, error, result) in
print(result!)
if success {
//Ihr Code hier
} else {
print(error?.localizedDescription ?? "")
}
}
Hier sind Schritt-für-Schritt-Anleitungen, um eine HTTP-Anfrage mit Swift unter Linux zu erstellen.
Erstellen Sie zunächst ein SwiftPM-Paket
mkdir swift-http && cd swift-http && swift package init --type executable
Ersetzen Sie dann den Inhalt von ./Sources/swift-http/main.swift
durch den folgenden Code:
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()
Führen Sie dann den Code aus
swift run
Beispiel-Ausgabe:
[6/6] Build abgeschlossen!
42 ist die Antwort auf die Ultimative Frage nach dem Leben, dem Universum und dem ganzen Rest.
Hinweis: Das DispatchSemaphore
wird verwendet, damit unser Programm nicht vor Erhalt einer Antwort beendet wird.
Sie könnten auch etwas Ähnliches wie dies getan haben:
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) }
Ein einfacher Ansatz in Swift 2.0, um eine HTTP GET-Anfrage zu machen
Die HTTP-Anfrage ist asynchron, daher benötigen Sie eine Möglichkeit, den zurückgegebenen Wert der HTTP-Anfrage zu erhalten. Dieser Ansatz verwendet Notifier und erstreckt sich über zwei Klassen.
Das Beispiel besteht darin, den Benutzernamen und das Passwort für ein Identifikationstoken mithilfe der Website http://www.example.com/handler.php?do=CheckUserJson&json= zu überprüfen. Die Datei heißt handler.php und enthält eine Switch-Anweisung zum do-Parameter für einen RESTful-Ansatz.
Im viewDidLoad richten wir den NotifierObserver ein, stellen den JSON ein und rufen die Funktion getHTTPRequest auf. Diese Funktion gibt den zurückgegebenen Parameter der HTTP-Anfrage an die Funktion checkedUsernameAndPassword zurück.
override func viewDidLoad() {
super.viewDidLoad()
// Einrichten des Notification-Observer, um das Ergebnis von Benutzername und Passwortprüfung zu erfassen
NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkedUsernameAndPassword:", name: CHECK_USERNAME_AND_PASSWORD, object: nil)
let username = GlobalVariables.USER_NAME
let password = GlobalVariables.PASSWORD
// Benutzername und Passwort überprüfen
if let jsonString = Utility.checkUsernameAndPasswordJson(username, password:password){
print("zurückgegebener JSON-String = \(jsonString)")
let url = CHECKUSERJSON+jsonString
// CHECKUSERJSON = http://www.example.com/handler.php?do=CheckUserJson&json=
// jsonString = {\"username\":\"demo\",\"password\":\"demo\"}"
// Das PHP-Skript bearbeitet eine JSON-Anfrage und gibt einen Zeichenfolgenidentifikator zurück
Utility.getHTTPRequest(url,notifierId: CHECK_USERNAME_AND_PASSWORD)
// Der zurückgegebene Identifikator wird an die Funktion checkedUsernameAndPassword gesendet, wenn er verfügbar ist.
}
}
Es gibt zwei statische Funktionen in Utility.swift, erstens zum Codieren des JSON und dann zum Ausführen des HTTP-Aufrufs.
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
}
}
und der HTTP-Anfrage
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("ungültige URL = \(urlString)")
}
}
Die Funktion sendNotification vervollständigt den Kreis. Beachten Sie, dass im Observer ein ":" am Ende der Selektorzeichenfolge vorhanden ist. Dadurch kann die Benachrichtigung in userInfo ein Nutzlast tragen. Ich gebe dies als String und als Int zurück.
static func sendNotification (key: String, message:String?, num: Int?){
NSNotificationCenter.defaultCenter().postNotificationName(
key,
object: nil,
userInfo: (["message": message!,
"num": "\(num!)"])
)
}
Beachten Sie, dass die Verwendung von HTTP altmodisch ist. Verwenden Sie lieber HTTPS siehe Wie lade ich eine HTTP-URL mit aktivierter App-Transport-Sicherheit in iOS 9?
Aktualisierung :- Xcode 13.0 & Swift 5+
HOL HTTP-ANFRAGE
let url = URL(string: "URL HIER")! //Geben Sie Ihre URL ein
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let safeData = data,
let response = response as? HTTPURLResponse,
error == nil else { // Überprüfen Sie auf grundlegende Netzwerkfehler
print("Fehler", error ?? "Unbekannter Fehler")
delegate?.onError(error!)
return
}
guard (200 ... 299) ~= response.statusCode else { // Überprüfen Sie auf HTTP-Fehler
print("Der Statuscode sollte 2xx sein, ist aber \(response.statusCode)")
print("Antwort = \(response)")
return
}
let responseString = String(data: safeData, encoding: .utf8)
print("Antwort-String = \(responseString)")
}
task.resume()
//Hier ist ein Beispiel, das für mich funktioniert hat
//Swift-Funktion, die eine Anfrage mit Schlüsselwerten an einen Server sendet
func insertRecords()
{
let usrID = txtID.text
let checkin = lblInOut.text
let comment = txtComment.text
// Die Adresse des Webservice
let urlString = "http://your_url/checkInOut_post.php"
// Das sind die Schlüsselwerte, die Sie als Teil der Post-Anfrage senden
let keyValues = "id=\(usrID)&inout=\(checkin)&comment=\(comment)"
// 1 - Erstellen Sie die Sitzung, indem Sie die Konfiguration abrufen und dann
// die Sitzung erstellen
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
// 2 - Erstellen Sie das URL-Objekt
if let url = NSURL(string: urlString){
// 3 - Erstellen Sie das Anfrage-Objekt
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// Setzen Sie die Schlüsselwerte
request.HTTPBody = keyValues.dataUsingEncoding(NSUTF8StringEncoding);
// 4 - Die Anfrage ausführen
let taskData = session.dataTaskWithRequest(request, completionHandler: {
(data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
println("\(data)")
// 5 - Etwas mit den zurückgegebenen Daten machen
if (data != nil) {
// Wir haben einige Daten zurückbekommen
println("\(data)")
let result = NSString(data: data , encoding: NSUTF8StringEncoding)
println("\(result)")
if result == "OK" {
let a = UIAlertView(title: "OK", message: "Die Anwesenheit wurde erfasst", delegate: nil, cancelButtonTitle: "OK")
println("\(result)")
dispatch_async(dispatch_get_main_queue()) {
a.show()
}
} else {
// Fehler anzeigen und etwas anderes tun
}
} else
{ // Es ist ein Fehler aufgetreten
println("Fehler beim Abrufen von Daten: \(error.localizedDescription)")
}
})
taskData.resume()
}
}
PHP-Code, um die Schlüsselwerte abzurufen
$empID = $_POST['id'];
$inOut = $_POST['inout'];
$comment = $_POST['comment'];