Translate AFNetworking POST constructingBodyWithBlock from Objective C to Swift -
i'm trying implement put version of below code in swift (so can implement put
attachment), found here: https://github.com/afnetworking/afnetworking/blob/master/afnetworking/afhttpsessionmanager.m
i'm having trouble getting compile, says variable task
used within own initial value
. thoughts?
objective 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; }
swift
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 convert 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 } } })
updated response
the error you're getting variable used within own initial value, means you're using constant task
before it's declared, you're using within declaration.
the proper way go around rewrite uploadtaskwithstreamedrequest()
return tuple of type (anyobject, nserror). unfortunately, involves more work. solution problem declare few variable outside uploadtaskwithstreamedrequest()
, , set them equal values captured inside closure. afterwards, can call completion blocks based on 2 optional binding tests, 1 of pass.
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 convert 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 }
original response
why bother doing this, when afnetworking comes ability make put request?
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; }