swift - 使用 swift POST 二进制数据
问题描述
我想通过 RxAlamofire、Alamofire 甚至没有任何库发布二进制数据,但经过几天的研究和尝试,我无法做到。
在这里,您可以找到我试图重现的请求的 POSTMAN 示例:
是一个 post 方法,带有 Authorization 和 Content-Type 标头以及附加的二进制数据。
我试图找到一些例子或相关的东西,但我找不到解决方案。我可以找到多部分表单数据示例,但是对于多部分表单数据,服务器不起作用(是外部 API)
如果有人可以指导我或向我展示一些示例代码。
这里以用于登录的代码为例,并向您展示我想要实现的目标:
public class APIClient: DataSource {
public static var shared: APIClient = APIClient()
private init(){}
public func login(email:String, password:String) -> Observable<LoginResponse> {
return RxAlamofire.requestJSON(APIRouter.login(email:email, password:password))
.subscribeOn(MainScheduler.asyncInstance)
.debug()
.mapObject(type: LoginResponse.self)
}
}
这里是 LoginResponse 对象:
public struct LoginResponse: Mappable {
var tokenId: String?
var userId: String?
public init?(map: Map) {}
public mutating func mapping(map: Map) {
tokenId <- map["id"]
userId <- map["userId"]
}
}
最后是扩展 URLRequestConvertible 的 APIRouter:
enum APIRouter: URLRequestConvertible {
case login(email: String, password: String)
private var method: HTTPMethod {
switch self {
case .login:
return .post
}
}
private var path: String {
switch self {
case .login:
return "users/login"
}
}
private var parameters: Parameters? {
switch self {
case .login(let email, let password):
return [APIConstants.LoginParameterKey.email: email, APIConstants.LoginParameterKey.password: password]
}
}
private var query: [URLQueryItem]? {
var queryItems = [URLQueryItem]()
switch self {
case .login:
return nil
}
}
func asURLRequest() throws -> URLRequest {
var urlComponents = URLComponents(string: APIConstants.ProductionServer.baseURL)!
if let query = query {
urlComponents.queryItems = query
}
var urlRequest = URLRequest(url: urlComponents.url!.appendingPathComponent(path))
// HTTP Method
urlRequest.httpMethod = method.rawValue
urlRequest.addValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue)
urlRequest.addValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
if let parameters = parameters {
do {
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch {
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
}
}
return urlRequest
}
}
先感谢您!
编辑转换成 RxAlamofire
使用下面的代码,我可以解决问题并将其转换为 RxSwift,但我想使用 RxAlamofire 来获得相同的结果:
public func upload(media: Data) -> Observable<ContentUri> {
let headers = [
"content-type": "image/png",
"authorization": "token header"
]
return Observable<ContentUri>.create({observer in
Alamofire.upload(media, to: "\(endPoint)/api/media/upload", headers: headers)
.validate()
.responseJSON { response in
print(response)
}
return Disposables.create();
})
}
解决方案
Alamofire.upload()
(返回一个UploadRequest
)可能会做你想做的事:
let headers = [
"Content-Type":"image/jpeg",
"Authorization":"sometoken",
]
let yourData = ... // Data of your image you want to upload
let endPoint = ...
Alamofire.upload(yourData, to: "\(endPoint)/api/media/upload", headers: headers)
.validate(statusCode: 200..<300)
.responseJSON { response in
// handle response
}
这个例子不包括 RxAlamofire - 但我很确定它有类似的upload
功能。我希望它有帮助!
推荐阅读
- .net - 在 IIS 上部署 Azure DevOps 网站时出错
- python - python re.split():如何保存一些分隔符(而不是使用括号来保存所有分隔符)
- css - 如何将css文件连接到wordpress标题的末尾?
- matplotlib - 进程在 matplotlib 中以退出代码 139(被信号 11:SIGSEGV 中断)完成
- vuejs2 - 为什么滑块中的图片无法正确显示
- javascript - 如何将三个文本表达式均匀对齐并垂直居中在一行中
- c++ - 使用向量时转储核心
- python - 在 PyQt5 中,弹出 QMessageBox 后,新父级在不同的 Qthread 中
- php - laravel 没有得到引导样式表
- laravel - laravel 保存 pdf 没有这样的文件或目录