简体   繁体   English

如何使用Alamofire发送字节?

[英]How to use Alamofire to send bytes?

I'm creating an application to download my university timetable. 我正在创建一个应用程序以下载我的大学时间表。 I've done the REST calls in Java first to demonstrate a prototype which works nicely. 我首先用Java完成了REST调用,以演示一个运行良好的原型。 And now I'd like to do it in Swift using Alamofire (or anything else which works). 现在,我想使用Alamofire(或其他可用的工具)在Swift中进行操作。

Below is the REST call in Java that I'm trying to replicate. 以下是我要复制的Java中的REST调用。

Client client = Client.create();

String authString = "UID=XXXXX&PASS=XXXXX";
byte[] authBytes = authString.getBytes();

WebResource webResouce = client.resource("https://access.adelaide.edu.au/sa/login.asp");

ClientResponse response = webResource.post(ClientResponse.class, authBytes);

if (response.getStatus != 302) {
throw new RuntimeException("Failed: HTTP code: " + response.getStatus());
}

However I'm having trouble sending the bytes properly. 但是我无法正确发送字节。 The server will actually accept any byte data (so you can see if it works without a UID or PASS) and respond with 302, which indicates that it works. 服务器实际上将接受任何字节数据(因此您可以查看它是否在没有UID或PASS的情况下工作),并以302响应,表明它可以工作。 Otherwise it'll send a 200 which means it didn't. 否则,它将发送200,表示没有发送。

I've had a few attempts of sending the UID and PASS in a parameter, getting their bytes and then putting them in a parameter etc etc. but nothing seems to work so far. 我已经尝试过在参数中发送UID和PASS,获取它们的字节,然后将它们放入参数中,等等。但是到目前为止,似乎没有任何效果。

Any help would be great, thanks! 任何帮助将是巨大的,谢谢!

You should use Alamofire's custom encoding technique (something like this). 您应该使用Alamofire的自定义编码技术(类似这样)。 This is my 3rd hour of Swift so bear with me. 这是我Swift的第三个小时,请耐心等待。

struct ByteEncoding: ParameterEncoding {
  private let data: Data

  init(data: Data) {
    self.data = data
  }

  func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
    var urlRequest = try urlRequest.asURLRequest()
    urlRequest.httpBody = data
    return urlRequest
  }
}

Alamofire.request(url: "url", method: .post, parameters: nil, encoding: ByteEncoding(data: authBytesAsData)

Documentation https://github.com/Alamofire/Alamofire#custom-encoding 文档https://github.com/Alamofire/Alamofire#custom-encoding

If you use a regular NSURLRequest you can just set the request body: 如果您使用常规的NSURLRequest,则可以设置请求正文:

let URL = NSURL(string: "https://access.adelaide.edu.au/sa/login.asp")!
let request = NSMutableURLRequest(URL: URL)
request.HTTPBody = // NSData you want as your body

Edit 编辑

As pointed out by @mattt himself, you can pass an NSURLRequest to Alamofire. 正如@mattt自己指出的那样,您可以将NSURLRequest传递给Alamofire。 No need for the hassle with custom parameter encoding as I answered first. 我首先回答时就无需使用自定义参数编码。 (See below) (见下文)


I don't exactly know how to do this using Alamofire, but it seems you can use a Custom parameter encoding with a closure. 我不完全知道如何使用Alamofire进行此操作,但是似乎可以在闭包中使用Custom参数编码。 I didn't test this but took it from the Alamofire unit test source: 我没有对此进行测试,但是从Alamofire单元测试源中获取了它:

let encodingClosure: (URLRequestConvertible, [String: AnyObject]?) -> (NSURLRequest, NSError?) = { (URLRequest, parameters) in
    let mutableURLRequest = URLRequest.URLRequest.mutableCopy() as NSMutableURLRequest
    mutableURLRequest.HTTPBody = parameters["data"]
    return (mutableURLRequest, nil)
}

let encoding: ParameterEncoding = .Custom(encodingClosure)

let URL = NSURL(string: "https://access.adelaide.edu.au/sa/login.asp")!
let URLRequest = NSURLRequest(URL: URL)
let data: NSData = // NSData you want as your body
let parameters: [String: AnyObject] = ["data": data]

let URLRequestWithBody = encoding.encode(URLRequest, parameters: parameters).0

Here's a quick example of how you could make this type of request. 这是一个简单的示例,说明如何进行此类请求。

import Alamofire

class BytesUploader {
    func uploadBytes() {
        let URLRequest: NSURLRequest = {
            let URL = NSURL(string: "https://access.adelaide.edu.au/sa/login.asp")!
            let mutableURLRequest = NSMutableURLRequest(URL: URL)
            mutableURLRequest.HTTPMethod = "POST"

            let authString = "UID=XXXXX&PASS=XXXXX"
            let authData = authString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
            mutableURLRequest.HTTPBody = authData

            return mutableURLRequest.copy() as NSURLRequest
        }()

        let request = Alamofire.request(URLRequest)
        request.response { request, response, data, error in
            if let response = response {
                println("Response status code: \(response.statusCode)")

                if response.statusCode == 302 {
                    println("Request was successful")
                } else {
                    println("Request was NOT successful")
                }
            } else {
                println("Error: \(error)")
            }
        }
    }
}

You need to encode your authorization string as an NSData object and then set that as the HTTPBody of the NSURLRequest . 您需要将授权字符串编码为NSData对象,然后将其设置为NSURLRequestHTTPBody This should match your Java code that you posted. 这应该与您发布的Java代码匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM