Класс Obj-C для выполнения асинхронного запроса

Я разрабатываю приложение для iPhone, в котором мне нужно использовать FQL Facebook для загрузки уведомлений пользователя. Поскольку мне нужно загружать эти уведомления в разных местах приложения, я хотел бы создать подкласс NSObject для загрузки и возврата этих уведомлений в виде массива. Я понимаю, что я должен сделать подкласс (NotificationLoader) и тогда я мог бы вызвать метод внутри этого, например, startLoading: и в идеальном мире этот метод просто возвращает массив, но не может, так как уведомления должны загружаться асинхронно. Я также должен принять во внимание, что асинхронный запрос может вернуть ошибку в connection:didFailWithError:

Может кто-нибудь дать мне подсказку или пример того, как я могу создать класс, который выполняет асинхронную загрузку и возвращает результат? Я полагаю, этот класс должен называться так:

NotificationLoader *notificationLoader = [NotificationLoader alloc] init];
NSArray *notifications = [notificationLoader startLoading];

Хотя я не уверен, что это лучший способ сделать это.

4 ответа

Решение

Если вы хотите, чтобы это было асинхронно, вы должны использовать шаблон делегирования. Определите протокол, который должен быть реализован классом, который вызывает NotificationLoader. При вызове startLoading метод должен запустить отдельный поток (или использовать NSURL для запуска асинхронного вызова) и загрузить все содержимое асинхронно. Когда это будет сделано, он вызовет либо метод FinishedLoadingResults:(NSArray*) для делегата (который объявлен в протоколе), либо "didFailWithError".

так что вы просто позвоните

 -(void) someMethod{
       NotificationLoader *notificationLoader = [NotificationLoader alloc] init];
       notificationLoader.delegate = self;
       [notificationLoader startLoading];
 }

 -(void) notificationLoaderDidLoadResults:(NSArray*) results
 {
       // This is the place where you get your results.
 } 

 -(void) notificationLoaderDidFailWithError:....
 {
       // or there was an error...
 }

Пример для вашего NotificationLoader:

 @protocol NotificationLoaderDelegate;
 @interface NotificationLoader : NSObject
 @property(nonatomic,retain) id<NotificationLoader> delegate;
 -(void) startLoading;
 @end

 // Define the methods for your delegate:
 @protocol NotificationLoaderDelegate <NSObject>

 -(void) notificationLoader:(NotificationLoader*) notifloader didFinishWithResults:(NSArray*) results;
 -(void) notificationLoader:(NotificationLoader*) notifloader didFailWithError;     

 @end

Реализация NotificationLoader

 @implementation NotificationLoader
 @synthesize delegate;

 -(void) startLoading{
       NSArray * myResults = ....;
       // Call delegate:
       [delegate notificationLoader:self didFinishWithResults:  myResults];
 }

Вам просто нужно создать URL-соединение и передать ему делегата. Это будет асинхронно.

NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];    

Я предпочитаю использовать ASIHTTPRequest для обработки как синхронных, так и асинхронных запросов.

Если вам нужно сделать HTTP-запрос, я настоятельно рекомендую использовать ASIHTTPRequest.

Другие вопросы по тегам