我已经创建了一个将异步收集来自url数据的数据的类,但是我对回调或其他什么的理解还不清楚,我试图找到一种通过让调用方法等待数据来重用我的类的简单方法在ApiManager类中返回或设置。当该过程完成时,我只需要在另一个类中唤醒一些东西。有些进程有单个请求,有些进程有多个,为什么你会注意到我在ApiManager类中使用[连接描述]。
ApiManager.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface ApiManager : NSObject<NSURLConnectionDelegate>
{
NSMutableDictionary *_dataDictionary;
}
- (void)urlRequest:(NSURLRequest *)url;
@property (strong, nonatomic) NSMutableArray *results;
@end
ApiManager.m
#import "ApiManager.h"
@implementation ApiManager
- (void)urlRequest:(NSURLRequest *)url {
[[NSURLConnection alloc] initWithRequest:url delegate:self];
}
// basic connection classes
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSMutableData *responceOjb = _dataDictionary[ [connection description] ];
[_dataDictionary setObject:responceOjb forKey:[connection description]];
}
// append any data we find
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSMutableData *responceOjb = _dataDictionary[ [connection description] ];
[responceOjb appendData: data];
[_dataDictionary setObject:responceOjb forKey:[connection description]];
}
// --
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
// wrap up and close the connect, move objects over to results or something
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[_results addObject:[connection description]];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
NSLog(@"%@",error);
}
@end
主视图控制器测试:
#import "ViewController.h"
#import "ApiManager.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self DoThisTest];
}
-(void)DoThisTest {
ApiManager *api = [[ApiManager alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",@"http://google.com"]]];
[api urlRequest:request];
if([api results]) {
NSLog(@"GOT DATA");
}
}
答案 0 :(得分:4)
嗯,有一些选择。您可以在ApiManager类中添加块属性:
@property (copy, nonatomic) void (^doneHandler)();
然后像这样调用该块:
self.doneHandler();
当您认为合适时(例如,在您的connectionDidFinishLoading:方法中),您将调用该块。
使用这种方法,块(回调)的定义将在视图控制器中发生,如下所示:
ApiManager *apiManager = [[ApiManager alloc] init];
apiManager.doneHandler = ^{
// Do whatever you need to do here.
};
或者,您可以使用如下签名向ApiManager添加方法:
- (void)sendRequestWithURL:(NSURL*)url completion:(void(^)())completion;
使用NSURLConnection(或更好的NSURLSession)基于块的API。这些API内置了回调,您只需在completion();
-[NSURLSession sendAsynchronousRequest:completion:].
最后,您可以定义ApiManagerDelegate协议。
- (void)apiManagerDidFinishReceivingData:(ApiManager*)sender;
并向您的ApiManager类添加委托属性。
@property (weak, nonatomic) id<ApiManagerDelegate>delegate;
在ViewController中分配ApiManager的代理:
ApiManager *apiManager = [[ApiManager alloc] init];
apiManager.delegate = self;
在ApiManager中调用NSURLConnectionDelegate回调实现中的委托方法,如下所示:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[_results addObject:[connection description]];
[self.delegate apiManagerDidFinishReceivingData:self];
}
在ViewController中实现委托方法:
- (void)apiManagerDidFinishReceivingData:(ApiManager*)sender {
// Do what you want to.
}
作为一个附录,有一些网络库可以为你做很多繁重的工作和忙碌工作,最值得注意的是AFNetworking,如果你只是想完成任务。而且,即使这是一个学术练习,你试图理解模式,看AFNetworking的API和实现(它的开源)将是非常有益的。
干杯