IPhone: File Upload using dispatch_async for background upload
I want to perform a image upload while the running application at the background. I am able to upload the image to the server using the code on this link. How can I upload a photo to a server with the iPhone?
I heard the NSUrlConnection can be asynchronous and it was used in the EPUploader. In my code, I add some extra method that will create a file in the application directory used for the EPUploader. During this creation of the file, I don't want it to create on the main thread of the application so I wrap all the code including the EPUploader itself with the dispatch_async on the global queue. That way I won't block the main thread while the file are creating.
It has no problem if I use dispatch_sync but dispatch_async I find something weird when I placed the breakpoint at NSUrlConnection connection :
- (void)upload
{
NSData *data = [NSData dataWithContentsOfFile:filePath];
//ASSERT(data);
if (!data) {
[self uploadSucceeded:NO];
return;
}
if ([data length] == 0) {
// There's no data, treat this the same as no file.
[self uploadSucceeded:YES];
return;
} /* blah blah */
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (!connection) {
[self uploadSucceeded:NO];
return;
}
else
return;
I went to debug at the breakpoint and instead of going to if statement, the debugger jumps to the first return statement of this method. After that, the selectors I passed on to this class never gets called. This happen only on dispatch_async and it work on dispatch_sync on the global queue.
Does anybody know how to solve this issue?
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(queue, ^{
NSAutoreleasePool *pool = [[NSAutorele开发者_如何学PythonasePool alloc] init];
self.uploadIndex = 0;
ALAsset *asset = [self.assets objectAtIndex:0];
[[FileUploader alloc] initWithAsset:[NSURL URLWithString:@"http://192.168.0.3:4159/default.aspx"]
asset:asset
delegate:self
doneSelector:@selector(onUploadDone:)
errorSelector:@selector(onUploadError:)];
//[self singleUpload:self.uploadIndex];
[pool release];
});
There are a couple of things that should be changed.
- Remove the
NSAutoreleasePool
, it is not needed. - Copy the block to the heap because it's life will probably exceed that of the calling code.
Example:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(queue, [[^{
self.uploadIndex = 0;
ALAsset *asset = [self.assets objectAtIndex:0];
[[FileUploader alloc] initWithAsset:[NSURL URLWithString:@"http://192.168.0.3:4159/default.aspx"]
asset:asset
delegate:self
doneSelector:@selector(onUploadDone:)
errorSelector:@selector(onUploadError:)];
} copy] autorelease]);
If you are using ARC (which you certainly are since you should be) there is no need for the copy
or autorelease
.
精彩评论