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" 为您构造一个对象(查看 .responseObject
和 JSONDecodable
在 tests 中作为示例)。
我们想发出 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" 为您构造一个对象(查看 .responseObject
和 JSONDecodable
在 tests 中作为示例)。