我试图在Swift中实现以下代码的PUT版本(因此我可以实现带附件的PUT
),可在此处找到:https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPSessionManager.m
我无法编译它,它说变量task
是used 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
}
}
})
答案 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;
}