2016-01-25 2 views
8

Wir wollen HTTP (S) Anfragen (GET) machen, um eine API aufzurufen. Das Problem ist, NSURLRequest ist (zur Zeit) nicht in der Foundation für Linux (https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSURLRequest.swift) implementiert.HTTP Anfrage in Swift ohne NSURLRequest

Gibt es noch andere Möglichkeiten, eine HTTP-Anfrage zu erstellen?

+1

[curl mapping für swift] (https://github.com/IBM-Swift/CCurl) IBM hat ein schnelles Paket für curl. Ich kann einfach nicht herausfinden, wie man eine einfache GET-Anfrage bekommt. –

Antwort

5

Es gibt ein nettes Projekt namens HTTPMiddleware das kann nützlich sein, es ist nur ein Middleware-Framework, aber es funktioniert gut.

Hier ist ein Codebeispiel:

import HTTP 
import HTTPMiddleware 

struct Middleware: HTTPRequestMiddlewareType { 
    func respond(request: HTTPRequest) -> HTTPRequestMiddlewareResult { 
     // You can change the request and pass it forward 
     return .Next(request) 

     // Or you can respond early and bypass the chain 
     return .Respond(HTTPResponse(statusCode: 404, reasonPhrase: "Not Found")) 
    } 
} 

struct Responder: HTTPResponderType { 
    func respond(request: HTTPRequest) -> HTTPResponse { 
     // May or may not be called depending on the middleware 
     return HTTPResponse(statusCode: 200, reasonPhrase: "OK") 
    } 
} 

let request = HTTPRequest(method: .GET, uri: URI(path: "/")) 
let chain = Middleware() >>> Responder() 
let response = chain.respond(request) 

Hier ist die offizielle page, Sie können auch eine JSON Parser in den Quellen finden, die für gemeinsame Anforderungen nützlich sein kann. Die Installation erfordert nur den uri_parser.

+0

Ich frage mich wirklich, warum es kein Swift-Paket mit Dokumentation gibt. Wenn Sie auf Golang schauen, müssen Sie lange suchen, um einen ohne vollständige Dokumente zu finden. Jedenfalls werde ich das versuchen und zu dir zurückkommen. –

+0

Ist nur schnell 2.2 und hat keine Aktivität in 6 Monaten gesehen. Also nicht mehr sehr nützlich. –

+0

Es gibt einige Einschränkungen, die ich kenne, aber es funktioniert –

2

Wenn man bedenkt, dass sich Swift unter Linux in ständiger Entwicklung befindet, ist der beste Ansatz meiner Meinung nach, keine ernsthafte Entwicklung zu betreiben, bis die Situation stabiler ist. Selbst wenn Sie das Hindernis überwinden, HTTP-Anfragen zu stellen, wird es wahrscheinlich andere unangenehme Überraschungen geben, da die Technologie unter Linux noch nicht ausgereift ist.

Wenn dies jedoch nur eine Frage der Neugier und des Lernens, sind hier einige Ideen, auch wenn ich sie selbst nicht versucht haben:

  • Vielleicht direkt Corefoundation C-APIs aufrufen funktionieren wird.
  • Schreiben Sie einen C-Wrapper, der die benötigte Schnittstelle mit guten alten C-Netzwerk-APIs bereitstellt. Dieser Ansatz würde wahrscheinlich mehr Aufwand erfordern als die anderen, da Sie viele Räder neu erfinden werden.
  • Schreiben Sie einen C-Wrapper, aber wickeln Sie eine höhere C-Bibliothek, die mit URLs funktioniert; Libcurl kommt mir in den Sinn.

Unabhängig davon, welche dieser Ansätze Sie verwenden, müssen Sie eine Schnittstelle mit C-Code. Eine Möglichkeit besteht darin, Systemmodule zu verwenden, siehe Importing a Swift module using a C library als möglichen Ausgangspunkt.

+0

danke für deine ausführliche Antwort. Du hast recht, vielleicht ist die beste Antwort warten. Ein c-Modul kann eine Option sein, vielleicht gibt es eine einfach zu bedienende API. – boxi

2

Betrachten wir folgende Lösung auf Basis von ccurl Bibliothek:

https://dl.dropboxusercontent.com/u/2504173/CurlSampleApp.tar.gz

Ich habe es auf Ubuntu 14.04

Swift 3.0 - neueste Entwickler-Version: https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a-ubuntu14.04.tar.gz

Nach Verpackung und Anleitung hat gut funktioniert allgemein:

https://swiftpkgs.ng.bluemix.net/package/SwiftOnTheServer/CCurl

Aber um Kompilierungsfehler zu beheben, musste ich in CCurl-Paket ändern.Folgende Zeile wurde hinzugefügt:

#include <stdint.h> 

Für die App Gebäude müssen Sie folgende in den App-Ordnern durchführen:

swift build 

Für App laufen Sie folgenden Befehl in den App-Ordnern ausführen müssen:

.build/debug/app 

Ich hoffe, es hilft. Stellen Sie Fragen, wenn überhaupt :)

+1

Ich versuche jetzt [bluemix-simple-http-client-swift] (https://github.com/ibm-bluemix-mobile-services/bluemix-simple-http-client-swift.git) Es ist ein Wrapper um CCurl und obwohl dort Beispielcode schlecht ist, wenn Sie es zum Kompilieren ändern, funktioniert es wirklich gut. –

+0

Ich überprüfe es –

+0

[Anforderung mit korrigiertem Beispielcode ziehen] (https://github.com/romainmenke/bluemix-simple-http-client-swift/tree/patch-2) –

0

nicht eine vollständige Antwort, aber vielleicht nützlich jemand:

Ich brauchte nur NSData(contentsOfURL: NSURL) so landete ich einen Wrapper für KituraNet Schreiben auf, die mit einem Verschluss tut dies. Ich überprüfe nur, ob Daten vorhanden sind und gebe das zurück.

Weil NSURL weit von voll implementiert ist, entschied ich mich auch, die URL als String für jetzt zu übergeben.

Es ist kein Ersatz für NSURLRequest, nur die gute alte Bequemlichkeit NSData(contentsOfURL: NSURL)

.Package(url: "https://github.com/IBM-Swift/Kitura-net.git", majorVersion: 0, minor: 15), 

import KituraNet 

extension NSData { 

    public static func contents(ofUrl urlString:String, completionHandler:((data:NSData?) -> Void)) { 

    let request = HTTP.request(urlString) { (response) in 

     guard let response = response else { 
     completionHandler(data: nil) 
     return 
     } 

     let responseData = NSMutableData() 
     do { 
     try response.readAllData(into: responseData) 
     completionHandler(data: responseData) 
     return 
     } catch { 
     completionHandler(data: nil) 
     return 
     } 
    } 
    request.end() 
    } 
} 
1

Seit Mitte 2017 gibt es SwiftyRequest Bibliothek von IBM, die auf Linux und iOS funktioniert. Ich habe es auf Linux versucht und scheint gut zu funktionieren.

Eine Anforderung sieht wie folgt aus (ein Beispiel von docs angepasst):

import SwiftyRequest 

let request = RestRequest(method: .get, url: "http://myApiCall/hello") 
request.responseString() { response in 
    switch response.result { 
    case .success(let result): 
     print("Success") 
    case .failure(let error): 
     print("Failure") 
    } 
} 

Wenn Sie JSON verwenden für die Antworten, es kann sogar konstruieren Sie ein Objekt auf der Basis eines „Schema“ Sie bieten (Schauen Sie sich .responseObject und JSONDecodable im tests für Beispiele an).