Возвращать данные из класса захвата данных из Интернета? - PullRequest
1 голос
/ 07 октября 2010

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

// FooClass.m
// DataGrabber is the class which is supposed to get values
dataGrabber = [[DataGrabber alloc] init];
xmlString = [dataGrabber getData:[NSDictionary dictionaryWithObjectsAndKeys:@"news", @"instruction", @"sport", @"section", nil]];

В этом примере он должен получать спортивные новости.Проблема состоит в том, что DataGrabber получает данные асинхронно и в итоге переходит от нескольких методов делегата NSURLConnection.Как узнать в FooClass, когда данные были получены?

Ответы [ 3 ]

3 голосов
/ 07 октября 2010

Шаблон делегата , используемый со строгим протоколом, очень полезен для этого (вот как DataGrabber узнает, когда выполняется NSURLConnection, верно?).Я написал несколько веб-API, которые используют информацию XML и JSON таким образом.

// In my view controller
- (void) viewDidLoad
{
  [super viewDidLoad];
  DataGrabber *dataGrabber = [[DataGrabber alloc] init];
  dataGrabber.delegate = self;
  [dataGrabber getData:[NSDictionary dictionaryWithObjectsAndKeys:@"news", @"instruction", @"sport", @"section", nil]];
}

Затем в вашем файле DataGrabber.h:

@protocol DataGrabberDelegate
@required
- (void) dataGrabberFinished:(DataGrabber*)dataGrabber;
- (void) dataGrabber:(DataGrabber*)dataGrabber failedWithError:(NSError*)error;
@end

И в DataGrabber.m:

- (void) getData:(NSDictionary*)dict
{
  // ... Some code to process "dict" here and create an NSURLRequest ...
  NSURLConnection *connection = [NSURLConnection connectionWithRequest:req delegate:self];
}

- (void) connectionDidFinishLoading:(NSURLConnection*)connection
{
  // ... Do any processing with the returned data ...

  // Tell our view controller we are done
  [self.delegate dataGrabberFinished:self];
}

Затем убедитесь, что Foo реализует методы протокола DataGrabberDelegate для обработки каждого случая.

Наконец, ваш DataGrabber имеет свойство delegate (убедитесь, что вы используете assign, но не сохраняете дляизбегайте сохранения циклов):

@property (nonatomic, assign) id<DataGrabberDelegate> delegate;

И когда асинхронные загрузки NSURLConnection завершаются внутри DataGrabber, они перезванивают вашему UIViewController в протоколе, изложенном выше, чтобы вы могли обновить пользовательский интерфейс.Если это ОДИН запрос, вы можете теоретически избавиться от DataGrabber и поместить его в свой контроллер представления, но мне нравится «разделять мои проблемы» - API и View Controller остаются раздельными.Он генерирует дополнительный слой, но не позволяет «тексту обрабатывать код» из контроллеров представления (особенно для кода синтаксического анализа JSON и XML).

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

Наконец, я написал более подробный пост в блоге об этом: Использование веб-API на iPhone

1 голос
/ 07 октября 2010

вы можете реализовать уведомления для вашего DataGrabber класса, которые отключаются каждый раз, когда вы получаете определенный объем данных (или когда загрузка заканчивается, если хотите), а затем способ уведомления (читайте об Уведомлениях в документации) может сделайте любую обработку, какую захотите.

Примечание: было бы полезно, если бы FooClass был делегатом DataGrabber

0 голосов
/ 17 февраля 2011

Я также использую уведомления для этого. Вот хорошее подробное объяснение как это настроить.

...