NSURLConnection загрузить файл асинхронно? - PullRequest
2 голосов
/ 01 сентября 2011

Я новичок в разработке ios, я читаю и ищу, но не могу найти рабочий пример или пример асинхронной загрузки файла с iphone на веб-сервер ..

I 'Я могу загружать синхронно, используя

[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

, это работает, но это блокирует мой основной поток.

NSUrlConnection имеет этот делегат (connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)

, но я понятия не имеюкак это осуществить.

Может кто-нибудь указать мне правильное направление?

Ответы [ 3 ]

13 голосов
/ 04 сентября 2011

Мне удалось заставить загрузку работать с NSURLConnection асинхронно с этим:

-(NSURLRequest *)postRequestWithURL: (NSString *)url

                                data: (NSData *)data   
                            fileName: (NSString*)fileName
{

// from http://www.cocoadev.com/index.pl?HTTPFileUpload

    //NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

    NSMutableURLRequest *urlRequest = [[[NSMutableURLRequest alloc] init] autorelease];
    [urlRequest setURL:[NSURL URLWithString:url]];
    //[urlRequest setURL:url];

    [urlRequest setHTTPMethod:@"POST"];

    NSString *myboundary = [NSString stringWithString:@"---------------------------14737809831466499882746641449"];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",myboundary];
    [urlRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];


    //[urlRequest addValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundry] forHTTPHeaderField:@"Content-Type"];

    NSMutableData *postData = [NSMutableData data]; //[NSMutableData dataWithCapacity:[data length] + 512];
    [postData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", myboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n", fileName]dataUsingEncoding:NSUTF8StringEncoding]];
    [postData appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [postData appendData:[NSData dataWithData:data]];
    [postData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", myboundary] dataUsingEncoding:NSUTF8StringEncoding]];

    [urlRequest setHTTPBody:postData];
    return urlRequest;
}

используется следующим образом:

    NSURLRequest *urlRequest = [self postRequestWithURL:urlString
                                                   data:aVideo.msgvid
                                               fileName:filename];

    uploadConnection =[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
5 голосов
/ 01 сентября 2011

Threading не является необходимым для такого рода проблем. Я бы посоветовал вам использовать асинхронную функциональность, встроенную в NSURLConnection:

NSURLConnection *connection = [NSURLConnection initWithRequest:request delegate:self];
[connection start];


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //Get your response, do stuff
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    //Show error, retry, etc
}

РЕДАКТИРОВАТЬ: Если вы действительно хотите загрузить файл и хотите отобразить индикатор выполнения, то вам следует обратиться к платформе ASIHTTPRequest, с которой вы можете получить более подробную информацию здесь: http://allseeing -i.com / ASIHTTPRequest /

Для загрузки POST-запроса с данными с использованием ASIHTTPRequest, вы должны сделать:

NSURL *url = [NSURL URLWithString:@"YOUR_URL_HERE"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"123" forKey:@"user_id"];
[request setData:someData withFileName:@"someData.jpg" andContentType:@"image/png" forKey:@"image"];
[request setProgressDelegate:self];
[request setDelegate:self];
[request startAsynchronous];

Опять же, обратитесь к ссылке выше для структуры и документации. Я настоятельно рекомендую это.

2 голосов
/ 01 сентября 2011

Вы не можете создать новый поток для этой задачи:

[NSThread detachNewThreadSelector:@selector(upload:) toTarget:self withObject:data];

А когда вы закончите загрузку, просто вызовите какой-нибудь реализованный метод в вашем основном потоке (например, uploaded):

[self performSelectorOnMainThread:@selector(uploaded) withObject:nil waitUntilDone:NO];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...