使用Swift快速发布二进制数据

时间:2018-08-21 06:19:03

标签: swift alamofire rx-swift rxalamofire

我想通过RxAlamofire,Alamofire甚至甚至没有任何库发布二进制数据,但经过几天的研究和尝试,我无法做到这一点。

在这里您可以找到我要重现的请求的POSTMAN示例:

captura de pantalla 2018-08-20 a las 13 42 36 captura de pantalla 2018-08-20 a las 13 42 48

是一种发布方法,带有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"]
    }

}

最后是APIRouter扩展URLRequestConvertible:

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();
        })
    }

1 个答案:

答案 0 :(得分:1)

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函数。希望对您有所帮助!