views:

995

answers:

5

Hi

like qik.com , ustream.com , I hope to know how to upload file in background via iPhone SDK 3.0 . Pls let me know . Thanks !

A: 

You can start a new thread for your file upload, look into the NSThread class heres a link http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSThread%5FClass/Reference/Reference.html ...that said you can also use asynchronousRequest from NSURLConnection which starts a thread for you heres a reference http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection%5FClass/Reference/Reference.html

Daniel
HiLike qik.com or ustream.com , when they upload content from iphone to server , it works via daemon . So even when out of the app with exit , the task is still on with background daemon . Is there any method that I can implement daemon process in a same way ? Thanks !!!
dvch
Aré u sure about this?
Daniel
A: 

You could do it this way (this is basically cut & paste from one of my projects). Credit goes to some post on the development forums, but I don't know who it was from anymore:

- (IBAction)startUpload:(id)sender {
    NSString *filename = [NSString stringWithFormat:@"iphone-%d.png", [NSDate timeIntervalSinceReferenceDate]];

    NSString *boundary = @"----BOUNDARY_IS_I";

    NSURL *url = [NSURL URLWithString:@"http://yourgreatwebsite.com/upload"];

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];

    [req setHTTPMethod:@"POST"];

    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];

    [req setValue:contentType forHTTPHeaderField:@"Content-type"];

    NSData *imageData = UIImagePNGRepresentation([imageView image]);

    // adding the body
    NSMutableData *postBody = [NSMutableData data];


    // first parameter an image
    [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"filename\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:imageData];

    // second parameter information
    [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    //[postBody appendData:[@"Content-Disposition: form-data; name=\"some_other_name\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //[postBody appendData:[@"some_other_value" dataUsingEncoding:NSUTF8StringEncoding]];
    //[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r \n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [req setHTTPBody:postBody];

    //start the spinner and deactivate the buttons...
    [self setButtonsEnabled:NO];


    [[NSURLConnection alloc] initWithRequest:req delegate:self];
  }

  #pragma mark urlconnection delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // this method is called when the server has determined that it
    // has enough information to create the NSURLResponse

    // it can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.
    // receivedData is declared as a method instance elsewhere
    [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];

    // inform the user
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Upload Error" message:[NSString stringWithFormat:@"The upload failed with this error: %@", [error localizedDescription]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    NSLog(@"Connection failed! Error - %@ %@",
       [error localizedDescription],
       [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
#ifdef DEBUG
    NSLog(@"upload succeeded!");
#endif

    // release the connection, and the data object
    [connection release];

    NSString *response = [NSString stringWithCString:[receivedData bytes] length:[receivedData length]]; 


#ifdef DEBUG
    NSLog(response);
#endif
}
Johannes Fahrenkrug
A: 

If you're refering to background upload while app is not running, you can't (OS doesn't allow it). If it's background while app is running, links and sample code posted here work just fine.

Rudi
+1  A: 

It's not clear what you mean by "in background", but if you just mean you want to upload asynchronously, you can use NSURLConnection, NSURLRequest, or you can use this excellent library called ASIHTTPRequest. It works great and provides a simple way to show download and upload progress.

Matt Long
+1 that looks like an awesome framework!
Dave DeLong
A: 

See this post for one (very well thought-out) response.

While it's not possible to upload files in the background when your app is NOT running, it's entirely possible to do so when your app IS running. This way you don't affect your foreground thread, plus you can likely augment this to show progress, etc.

Joe D'Andrea