将AFNetworking POST constructBodyWithBlock从Objective C转换为Swift

时间:2015-04-23 02:25:33

标签: objective-c swift afnetworking-2

我试图在Swift中实现以下代码的PUT版本(因此我可以实现带附件的PUT),可在此处找到:https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPSessionManager.m

我无法编译它,它说变量taskused within its own initial value。有什么想法吗?

目标C

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
     constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                       success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                       failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
    NSError *serializationError = nil;
    NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
    if (serializationError) {
        if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
#pragma clang diagnostic pop
        }

        return nil;
    }

    __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
        if (error) {
            if (failure) {
                failure(task, error);
            }
        } else {
            if (success) {
                success(task, responseObject);
            }
        }
    }];

    [task resume];

    return task;
}

夫特

func PUT(URLString: String!, parameters: AnyObject!, constructingBodyWithBlock block: ((AFMultipartFormData!) -> Void)!,
    success: ((NSURLSessionDataTask!, AnyObject!) -> Void)!,
    failure: ((NSURLSessionDataTask!, NSError!) -> Void)!) -> NSURLSessionDataTask! {

    let urlX = "http://localhost/\(URLString)"  //still need to convert to baseURL

    var serializationError:NSErrorPointer = nil

    let request:NSMutableURLRequest = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: urlX, parameters: parameters as! [NSObject : AnyObject]!, constructingBodyWithBlock: block, error: serializationError)

    let task:NSURLSessionDataTask = self.uploadTaskWithStreamedRequest(request, progress: nil, completionHandler: { (response: NSURLResponse!, responseObject: AnyObject!, error: NSError!) -> Void in
        if ((error) != nil) {
            if ((failure) != nil) {
                failure(task, error)  <-- error
            }
        } else {
            if ((success) != nil) {
                success(task, responsObject)  <-- error
            }
        }
    })

1 个答案:

答案 0 :(得分:0)

更新回复

您获得的错误是 变量在其自己的初始值 中使用,这意味着您在声明之前基本上使用常量task ,当你在声明中使用它时。

解决这个问题的正确方法是重写uploadTaskWithStreamedRequest()以返回类型元组(AnyObject,NSError)。不幸的是,这涉及更多的工作。我的解决方案是在uploadTaskWithStreamedRequest()之外声明一些变量,并将它们设置为等于闭包内捕获的值。之后,您可以根据两个可选的绑定测试调用完成块,其中只有一个将通过。

func PUT(URLString: String!, parameters: AnyObject!, constructingBodyWithBlock block: ((AFMultipartFormData!) -> Void)!,
    success: ((NSURLSessionDataTask!, AnyObject!) -> Void)!,
    failure: ((NSURLSessionDataTask!, NSError!) -> Void)!) -> NSURLSessionDataTask! {

        let urlX = "http://localhost/\(URLString)"  //still need to convert to baseURL

        var serializationError:NSErrorPointer = nil

        let request:NSMutableURLRequest = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: urlX, parameters: parameters as! [NSObject : AnyObject]!, constructingBodyWithBlock: block, error: serializationError)

        var outerError: NSError?
        var outerResponseObject: AnyObject?
        let task = self.uploadTaskWithStreamedRequest(request, progress: nil, completionHandler: { (response: NSURLResponse!, responseObject: AnyObject!, error: NSError!) -> Void in
            if ((error) != nil) {
                if ((failure) != nil) {
                    outerError = error
                }
            } else {
                if ((success) != nil) {
                    outerResponseObject = responseObject
                }
            }
        })

        if let outerError = outerError {
            failure(task, outerError)
        }

        if let outerResponseObject: AnyObject = outerResponseObject {
            success(task, outerResponseObject)
        }

        return task
}

原始回复

AFNetworking 能够发出PUT请求时,为什么还要费心呢?

https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPSessionManager.m#L186

- (NSURLSessionDataTask *)PUT:(NSString *)URLString
                   parameters:(id)parameters
                      success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                      failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure];

    [dataTask resume];

    return dataTask;
}