如何创建一个简单的 NSURLRequest 回调?
How to create a simple NSURLRequest Callback?
我创建了一个 class,它将异步地从 url 数据中收集数据,但是我对回调或其他内容的理解还不清楚,我正在尝试找到一种简单的方法来重用我的class 通过让调用方法等待数据返回或在 ApiManager class 中设置。当该过程完成时,我只需要在另一个 class 中唤醒一些东西。有些进程有单个请求,而其他进程有多个,为什么你会注意到我在 ApiManager class 中使用 [connection description]。
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");
}
}
好吧,有几个选项。您可以在 ApiManager class:
上添加一个块 属性
@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 具有内置的回调,您只需在 -[NSURLSession sendAsynchronousRequest:completion:].
的完成块内调用 completion();
最后,您可以定义一个 ApiManagerDelegate 协议。
- (void)apiManagerDidFinishReceivingData:(ApiManager*)sender;
并向您的 ApiManager class 添加委托 属性。
@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 和实现(它是开源的)也会很有启发性。
干杯
我创建了一个 class,它将异步地从 url 数据中收集数据,但是我对回调或其他内容的理解还不清楚,我正在尝试找到一种简单的方法来重用我的class 通过让调用方法等待数据返回或在 ApiManager class 中设置。当该过程完成时,我只需要在另一个 class 中唤醒一些东西。有些进程有单个请求,而其他进程有多个,为什么你会注意到我在 ApiManager class 中使用 [connection description]。
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");
}
}
好吧,有几个选项。您可以在 ApiManager class:
上添加一个块 属性@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 具有内置的回调,您只需在 -[NSURLSession sendAsynchronousRequest:completion:].
completion();
最后,您可以定义一个 ApiManagerDelegate 协议。
- (void)apiManagerDidFinishReceivingData:(ApiManager*)sender;
并向您的 ApiManager class 添加委托 属性。
@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 和实现(它是开源的)也会很有启发性。
干杯