457 Stimmen

Wie man in Swift eine HTTP-Anfrage stellt?

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?

2voto

Naresh Punkte 14268

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 ?? "")
    }
}

2voto

Chris Punkte 1930

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) }

1voto

user462990 Punkte 5328

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?

1voto

Quick learner Punkte 9420

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()

0voto

Ali Punkte 31

//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'];

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X