Swift 中没有 NSURLRequest 的 HTTP 请求

HTTP Request in Swift without NSURLRequest

我们想发出 HTTP(S) 请求 (GET) 来调用 API。问题是,NSURLRequest(目前)未在 Linux (https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSURLRequest.swift).

基金会中实施

还有其他创建 HTTP 请求的可能性吗?

考虑到 Linux 上的 Swift 正在 fast-evolving 工作中,我认为最好的方法是在情况更加稳定之前推迟进行任何认真的开发。即使您克服了发出 HTTP 请求的障碍,由于 Linux.

上的技术不成熟,也可能会出现其他令人不快的意外情况

但是,如果这只是好奇和学习的问题,这里有一些想法,尽管我自己还没有尝试过:

  • 也许直接调用 CoreFoundation C API 会起作用。
  • 使用良好的旧 C 网络 API 编写一个 C 包装器,它提供您需要的接口。这种方法可能需要比其他方法更多的努力,因为你会 re-inventing 很多轮子。
  • 编写一个 C 包装器,但包装一个 higher-level 与 URL 一起使用的 C 库;想到 libcurl。

无论采用哪种方法,您都需要与 C 代码交互。一种方法是使用系统模块,请参阅 Importing a Swift module using a C library 作为可能的起点。

有一个名为 HTTPMiddleware 的好项目很有用,它只是一个中间件框架,但运行良好。

这是一个代码示例:

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)

这是官方的 page,您还可以在源代码中找到一个 JSON 解析器,它对常见的请求很有用。 安装只需要 uri_parser.

考虑以下基于 ccurl 库的解决方案:

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

我是在 Ubuntu 14.04

做的

Swift 3.0 - 最新开发版本: https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a-ubuntu14.04.tar.gz

以下软件包和说明总体上运行良好:

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

但为了修复编译错误,我不得不修改 CCurl 包中的 sots_curl.h。添加了以下行:

#include <stdint.h>

对于应用程序构建,您需要在应用程序文件夹中执行以下操作:

swift build

对于应用程序运行,您需要在应用程序文件夹中执行以下命令:

.build/debug/app

希望对您有所帮助。有问题就问:)

不是完整的答案,但可能对某人有用:

我只需要 NSData(contentsOfURL: NSURL) 所以我最终为 KituraNet 编写了一个包装器,它用一个闭包来完成这个。我只是检查是否有数据和 return 那。

因为 NSURL 远未完全实施,我还决定暂时将 url 作为 String 传递。

它不是 NSURLRequest 的替代品,只是 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()
  }
}

自 2017 年年中以来,IBM 的 SwiftyRequest 库可在 Linux 和 iOS 上运行。我已经在 Linux 上试过了,似乎工作正常。

发出请求如下所示(改编自文档中的示例):

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

如果您使用 JSON 作为响应,它甚至可以根据您提供的 "schema" 为您构造一个对象(查看 .responseObjectJSONDecodabletests 中作为示例)。