【问题标题】:HTTP Request in Swift without NSURLRequest没有 NSURLRequest 的 Swift 中的 HTTP 请求
【发布时间】:2016-01-25 16:12:06
【问题描述】:

我们希望发出 HTTP(S) 请求 (GET) 来调用 API。问题是,NSURLRequest(目前)没有在 Linux 基金会 (https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSURLRequest.swift) 中实现。

还有其他方法可以创建 HTTP 请求吗?

【问题讨论】:

  • curl mapping for swift IBM 有一个用于 curl 的 swift 包。我只是不知道如何让它做一个简单的 GET 请求。

标签: linux swift httprequest


【解决方案1】:

有一个名为 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

【讨论】:

  • 我真的很想知道为什么没有一个带有文档的 Swift 包。如果您查看 golang,您将不得不寻找一个没有完整文档的冗长且难以找到的。无论如何,我会试试这个并回复你。
  • 只有 swift 2.2 并且在 6 个月内没有看到活动。所以不再很有用了。
  • 嗯,我得到的 100 多个构建错误说它没有......我很抱歉,但是一个只有 Swift 2.2 并且在 6 个月内没有更新的包不是一个好的选择用于生产软件
  • 对不起,您使用的是什么 swift 版本?其实swift 2.2总是更稳定,你有旧版本吗?你的发行版是什么? Swift 发布:github.com/apple/swift/branches 您现在在官方页面上看不到任何活动,因为没有发现问题。
  • 我已经将我在 Swift for linux 中所做的一切都 docker 化了。我当前的基础镜像是ibmcom/swift-ubuntu:latest。如果我没记错的话,它使用 Swift 3.0 并运行 Ubuntu 15。在我的主机上,我使用官方 swift 2.2 运行 OSX
【解决方案2】:

考虑以下基于 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

希望对您有所帮助。如果有问题,请提出问题:)

【讨论】:

【解决方案3】:

考虑到 Linux 上的 Swift 正在快速发展,我认为最好的方法是推迟进行任何认真的开发,直到情况更加稳定。即使您克服了发出 HTTP 请求的障碍,由于技术在 Linux 上的不成熟,也可能会出现其他令人不快的意外。

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

  • 也许直接调用 CoreFoundation C API 会起作用。
  • 使用良好的旧 C 网络 API 编写一个 C 包装器,提供您需要的接口。这种方法可能比其他方法需要更多的努力,因为您将重新发明很多轮子。
  • 编写一个 C 包装器,但包装一个使用 URL 的更高级别的 C 库;想到 libcurl。

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

【讨论】:

  • 感谢您的详细回答。你是对的,也许最好的答案是等待。一个 c 模块可以是一个选项,也许有一个易于使用的 api。
【解决方案4】:

自 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 作为响应,它甚至可以根据您提供的“模式”为您构造一个对象(例如,请查看 tests 中的 .responseObjectJSONDecodable)。

【讨论】:

    【解决方案5】:

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

    我只需要NSData(contentsOfURL: NSURL),所以我最终为 KituraNet 编写了一个包装器,它通过闭包来实现这一点。我只是检查是否有数据并返回。

    因为NSURL 远未完全实现,我还决定暂时将网址作为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()
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多