Objective-C: запросы к серверу в потоке (например, AsyncTask в Android) - PullRequest
11 голосов
/ 24 ноября 2010

Я хотел бы запустить запрос к серверу, вы можете отменить.

Моя идея - запустить запрос в потоке, чтобы пользовательский интерфейс не зависал.Таким образом, вы можете завершить весь поток, включая запрос, нажав кнопку «Отмена».

С Android это работает: запрос к серверу запускается в «AsyncTask» и в «onReturn ()»-метод Я могу реагировать, как только запрос сервера завершится.

Как я могу реализовать это с помощью Objective-C на iOS?Моя первая попытка была "NSInvocationOperation".Вы можете отменить операцию, но ее трудно обработать, когда запрос завершен и результаты доступны.Я думаю, что NSInvocationOperation не является решением моей проблемы.

Что бы вы порекомендовали мне?Является ли NSThread правильным выбором для меня?

Большое спасибо!

Ответы [ 5 ]

5 голосов
/ 25 ноября 2010

Примечание!

Чт - очень старый ответ, теперь он доступен только для исторических целей.

Замечательная библиотека ASIHttpRequest нетдольше существует;технология сейчас совершенно другая.


Это невероятно просто сделать с помощью ASIHttpRequest.

(Асинхронный - это так просто, нет причины, по которой вы бы никогда этого не делали)-синхронно.)

Вот некоторые грубые выдержки, которые могут помочь вам начать.

...
ASIFormDataRequest *request;
...
NSURL *url = [NSURL URLWithString:@"https://blah.blah/blah.cgi?blah"];
request = [ASIFormDataRequest requestWithURL:url];

[request setPostValue:@"fred" forKey:@"username"];
[request setPostValue:@"flint" forKey:@"passie"];
[request setPostValue:@"stone" forKey:@"town"];

// send up data...
[request setData:[NSData dataWithBytes:blah length:blah] forKey:@"thefile"];

// or perhaps something like...
[request setData:imageData withFileName:@"blah.png"
        andContentType:@"image/jpeg" forKey:@"photoimage"];

[request setDelegate:self];
[request setDidFinishSelector:@selector(postingDone:)];
[request setDidFailSelector:@selector(postingDoneProblem:)];
[request startAsynchronous];
...

-(void) postingDone:(ASIHTTPRequest *)request
    {
    // it worked
    }
-(void) postingDoneProblem:(ASIHTTPRequest *)request
    {
    // failed
    }

Не может быть проще.Вы просто вводите поля и значения.

По вашему вопросу, вот как вы отменяете запрос "в полете" ... простоустановите для делегата значение nil, а затем «отмените» его.

  [myRequest setDelegate:nil];
  [myRequest cancel];
  [myRequest release];

ASIHttpRequest - это «библиотека чудес».Если вы новичок в iOS, ASIHttpRequest просто САМАЯ наиболее используемая сторонняя библиотека.По сути, каждое приложение для iPhone из 300 000 приложений для iPhone использует его.

Если это вообще возможно, ОБЯЗАТЕЛЬНО пожертвуйте парню несколько долларов - если он перестанет поддерживать эту библиотеку, 100 000 программистов на iPhone будут ошибаться!

документация тривиальна, за ней может следовать ребенок:
http://allseeing -i.com / ASIHTTPRequest / How-to-use
"Создание асинхронного запроса"

это, наверное, почти наверняка, самая удивительно простая сетевая библиотека на любой платформе.Делать то, что вы описываете, тривиально, к счастью.Наслаждайтесь.

2 голосов
/ 24 ноября 2010

Встроенный асинхронный сетевой код Cocoa не основан на потоках, но работает с событиями цикла выполнения, но результат (асинхронные соединения) тот же.

Создайте NSURLConnection с +[NSURLConnection connectionWithRequest:delegate:]. Назначенный вами делегат будет проинформирован о ходе соединения и может в любое время отменить его с помощью -[NSURLConnection cancel].

2 голосов
/ 24 ноября 2010

NSURLConnection является асинхронным по умолчанию и поддерживает отмену, а также методы делегирования, когда соединение установлено, данные получены или весь запрос завершен.

Также передача данных происходит в фоновом режиме, так что пользовательский интерфейс остаетсяотзывчивый.

1 голос
/ 25 ноября 2010

Следует обратить внимание на рекомендации по использованию +[NSURLConnection connectionWithRequest:delegate:], так как он должен вызываться только из основного потока начиная с iOS 4.

см. http://blog.mugunthkumar.com/coding/ios4-issue-nsurlconnection-and-nsoperation/ для примера того, как бороться с этим.

1 голос
/ 24 ноября 2010

Извлечение ASIHTTPRequest , в частности, подкласс ASINetworkQueue, который описывается как:

ASINetworkQueue

Подкласс NSOperationQueue, который может использоваться для отслеживания прогресса в несколько запросов.

Я использовал ASIHTTPRequest только для одного синхронного запроса на загрузку непосредственно на диск, что было легко реализовать, но я слышал хорошие сообщения об использовании очередей для одновременного управления несколькими асинхронными серверными запросами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...