从网上从数据抓取类返回数据? [英] Returning data from data-grabbing class from web?

查看:114
本文介绍了从网上从数据抓取类返回数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个允许我从Web服务获取请求数据的类。我坚持如何返回值。

  // FooClass.m 
// DataGrabber是类应该得到值
dataGrabber = [[DataGrabber alloc] init];
xmlString = [dataGrabber getData:[NSDictionary dictionaryWithObjectsAndKeys:@news,@instruction,@sport,@section,nil]];

在这个例子中,它应该得到体育新闻。问题是DataGrabber异步获取数据并最终从几个NSURLConnection委托方法跳转。如何在收到数据时知道FooClass?

解决方案

委托模式与严格一起使用协议对此非常有用(这就是DataGrabber在NSURLConnection完成时会发现的,对吗?)。我编写了许多以这种方式使用XML和JSON信息的Web API。

  //在我的视图控制器中
- (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 *)错误;
@end

在DataGrabber.m中:

   - (void)getData:(NSDictionary *)dict 
{
// ...这里处理dict的一些代码并创建NSURLRequest ...
NSURLConnection * connection = [NSURLConnection connectionWithRequest:req delegate:self];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// ...使用返回的数据进行任何处理...

//告诉我们的视图控制器我们完成了
[self.delegate dataGrabberFinished:self];
}

然后确保Foo实现了DataGrabberDelegate协议方法来处理每种情况。



最后,您的DataGrabber有一个委托属性(确保使用assign,而不是保留以避免保留周期) :

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

当在DataGrabber内完成NSURLConnection异步加载时,他们会在协议中回调你的UIViewController上面列出了以便您可以更新UI。如果它是一个请求,理论上你可以摆脱DataGrabber并将它放在你的视图控制器中,但我喜欢分离我的顾虑 - API和View Controller保持独立。它会生成一个额外的层,但它会将文本处理代码保留在视图控制器之外(特别是对于JSON和XML解析代码)。



我做了很多成功的时间 - 另一个关键是向用户提供页面加载的一些反馈是好的 - 打开状态栏中的活动指示器,向他们显示UIActivityIndi​​cator等,然后当你的委托回调回来时无论成功还是失败,你都可以摆脱它。



最后,我写了一篇更详细的博客文章:在iPhone上使用Web API / p>

I'm trying to create a class which will let me get requested data from a web service. I'm stuck on how to return the values.

// 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]];

In this example, it's supposed to get the sports news. The problem is that the DataGrabber gets the data asynchronously and ends up hopping from several NSURLConnection delegate methods. How do know in FooClass when data has been received?

解决方案

The delegate pattern used with a strict protocol is very useful for this (that's how DataGrabber would find out when NSURLConnection is done, right?). I have written a number of Web APIs that consume XML and JSON information this way.

// 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]];
}

Then in your DataGrabber.h file:

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

And in 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];
}

Then make sure that Foo is implements the DataGrabberDelegate protocol methods to handle each case.

Finally, your DataGrabber has a delegate property (make sure you use assign, not retain to avoid retain cycles):

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

And when the NSURLConnection asynchronous loads are finished inside of DataGrabber, they call back to your UIViewController in the protocol laid out above so that you can update the UI. If it's ONE request, you could theoretically get rid of DataGrabber and put it inside your view controller, but I like to "separate my concerns" - API and View Controller stay separate. It generates an extra layer, but it keeps "text processing code" out of the view controllers (specifically for JSON and XML parsing code).

I've done this many times with success - one other key is that it's good to provide the user with some feedback that a page is loading - turn on the activity indicator in the status bar, show them a UIActivityIndicator, etc., and then when your delegate callback comes back with either success or failure, you get rid of it.

Finally, I've written a more detailed blog post about this: Consuming Web APIs on the iPhone

这篇关于从网上从数据抓取类返回数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆