Iphone -[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]的iOS4实现?
如何为iOS<5实现Iphone -[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]的iOS4实现?,iphone,objective-c,ios,nsurlconnection,nsurlconnectiondelegate,Iphone,Objective C,Ios,Nsurlconnection,Nsurlconnectiondelegate,如何为iOS
-[NSURLConnection sendAsynchronousRequest:queue:completionHandler::
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
#import <objc/runtime.h>
#import "NSURLConnection+iOS4.h"
// Dynamically add -[NSURLConnection sendAsynchronousRequest:queue:completionHandler:].
void *sendAsynchronousRequest4(id self, SEL _cmd, NSURLRequest *request, NSOperationQueue *queue, void (^handler)(NSURLResponse*, NSData*, NSError*));
void *sendAsynchronousRequest4(id self, SEL _cmd, NSURLRequest *request, NSOperationQueue *queue, void (^handler)(NSURLResponse*, NSData*, NSError*)) {
// How should we implement this?
}
@implementation NSURLConnection (SendAsync)
+ (void)load {
SEL sendAsyncSelector = @selector(sendAsynchronousRequest:queue:completionHandler:);
if (![NSURLConnection instancesRespondToSelector:]) {
class_addMethod([self class], sendAsyncSelector, (IMP)sendAsynchronousRequest4, "v@:@@@");
}
}
@end
#endif
#如果需要IPHONE操作系统版本最低版本<\uu IPHONE 5\u 0
#进口
#导入“NSURLConnection+iOS4.h”
//动态添加-[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]。
void*sendAsynchronousRequest4(id self、SEL\u cmd、NSURLRequest*请求、NSOperationQueue*队列、void(^handler)(NSURLResponse*、NSData*、NSError*);
void*sendAsynchronousRequest4(id self、SEL\u cmd、NSURLRequest*请求、NSOperationQueue*队列、void(^handler)(NSURLResponse*、NSData*、NSError*)){
//我们应该如何实施这一点?
}
@实现NSURLConnection(SendAsync)
+(空)荷载{
SEL sendAsyncSelector=@selector(sendAsynchronousRequest:queue:completionHandler:);
如果(![NSURLConnection instancesRespondToSelector:){
类_addMethod([self class],sendAsyncSelector,(IMP)sendAsynchronousRequest4,“v@@@@@@1”);
}
}
@结束
#恩迪夫
我会选择已经构建好的框架,比如ASIHTTPRequest(不再开发,但仍然很好)或RestKit(我以前从未使用过它,但听说它很不错)。这些将在不同版本的操作系统中为您提供相同的功能(异步http请求)
ifdef不是最好的选择,因为它们是在编译时完成的,并且您不会为每个平台编译单独的应用程序版本
您可能会在运行时做一些恶作剧来让它工作,但这似乎比它的价值更麻烦。我通常会创建一个子类NSOperation,并在操作的主要方法中执行同步请求。为了调用该操作,我创建了一个子类的实例,并将其抛出到队列(而不是主线程)中。然后,当操作完成时,它要么使用接收到的数据调用委托,要么通过NSNotificationCenter发布通知。
//NSURLConnection+SendAsync.h
// NSURLConnection+SendAsync.h
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
#import <Foundation/Foundation.h>
@interface NSURLConnection (SendAsync)
@end
#endif
// NSURLConnection+SendAsync.m
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
typedef void (^URLConnectionCompletionHandler)(NSURLResponse *response, NSData *data, NSError *error);
@interface URLConnectionDelegate : NSObject <NSURLConnectionDataDelegate>
@property (nonatomic, strong) NSURLResponse *response;
@property (nonatomic, strong) NSMutableData *data;
@property (nonatomic, strong) NSOperationQueue *queue;
@property (nonatomic, copy) URLConnectionCompletionHandler handler;
@end
@implementation URLConnectionDelegate
@synthesize response;
@synthesize data;
@synthesize queue;
@synthesize handler;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)theResponse {
self.response = theResponse;
[data setLength:0]; // reset data
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData {
[data appendData:theData]; // append incoming data
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.data = nil;
if (handler) { [queue addOperationWithBlock:^{ handler(response, nil, error); }]; }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// TODO: Are we passing the arguments to the block correctly? Should we copy them?
if (handler) { [queue addOperationWithBlock:^{ handler(response, data, nil); }]; }
}
@end
#import <objc/runtime.h>
#import "NSURLConnection+SendAsync.h"
// Dynamically add @property (nonatomic,readonly) UIViewController *presentingViewController.
void sendAsynchronousRequest4(id self, SEL _cmd, NSURLRequest *request, NSOperationQueue *queue,
URLConnectionCompletionHandler handler);
void sendAsynchronousRequest4(id self, SEL _cmd, NSURLRequest *request, NSOperationQueue *queue,
URLConnectionCompletionHandler handler) {
URLConnectionDelegate *connectionDelegate = [[URLConnectionDelegate alloc] init];
connectionDelegate.data = [NSMutableData data];
connectionDelegate.queue = queue;
connectionDelegate.handler = handler;
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request
delegate:connectionDelegate];
NSAssert(connection, nil);
}
@implementation NSURLConnection (SendAsync)
+ (void)load {
SEL sendAsyncSelector = @selector(sendAsynchronousRequest:queue:completionHandler:);
if (![NSURLConnection instancesRespondToSelector:sendAsyncSelector]) {
class_addMethod(object_getClass([self class]),
sendAsyncSelector, (IMP)sendAsynchronousRequest4, "v@:@@@");
}
}
@end
#endif
#如果需要IPHONE操作系统版本最低版本<\uU IPHONE 5\u 0
#进口
@接口NSURLConnection(SendAsync)
@结束
#恩迪夫
//NSURLConnection+SendAsync.m
#如果需要IPHONE操作系统版本最低版本<\uU IPHONE 5\u 0
typedef void(^URLConnectionCompletionHandler)(NSURLResponse*响应,NSData*数据,NSError*错误);
@接口URLConnectionLegate:NSObject
@性质(非原子,强)NSURLResponse*响应;
@属性(非原子,强)NSMutableData*数据;
@属性(非原子,强)NSOperationQueue*队列;
@属性(非原子,复制)URLConnectionCompletionHandler;
@结束
@实现URLConnectionLegate
@综合反应;
@综合数据;
@综合队列;
@综合处理程序;
-连接:(NSURLConnection*)连接接收方响应:(NSURResponse*)响应{
自我反应=反应;
[数据集长度:0];//重置数据
}
-(void)连接:(NSURLConnection*)连接未接收数据:(NSData*)数据{
[数据追加数据:theData];//追加传入数据
}
-(无效)连接:(NSURLConnection*)连接失败错误:(NSError*)错误{
[UIApplication sharedApplication].networkActivityIndicatorVisible=否;
self.data=nil;
if(handler){[queue addOperationWithBlock:^{handler(response,nil,error);}];}
}
-(无效)连接IDFinishLoading:(NSURLConnection*)连接{
[UIApplication sharedApplication].networkActivityIndicatorVisible=否;
//TODO:我们是否正确地将参数传递给块?我们是否应该复制它们?
if(handler){[queue addOperationWithBlock:^{handler(response,data,nil);}];}
}
@结束
#进口
#导入“NSURLConnection+SendAsync.h”
//动态添加@property(非原子,只读)UIViewController*presentingViewController。
void sendAsynchronousRequest4(id self、SEL\u cmd、NSURLRequest*请求、NSOperationQueue*队列、,
URLConnectionCompletionHandler);
void sendAsynchronousRequest4(id self、SEL\u cmd、NSURLRequest*请求、NSOperationQueue*队列、,
URLConnectionCompletionHandler){
urlconnectionelegate*connectionelegate=[[urlconnectionelegate alloc]init];
connectionDelegate.data=[NSMutableData];
connectionLegate.queue=队列;
connectionLegate.handler=处理程序;
NSURLConnection*connection=[NSURLConnection connectionWithRequest:request
代表:ConnectionLegate];
NSAssert(连接,无);
}
@实现NSURLConnection(SendAsync)
+(空)荷载{
SEL sendAsyncSelector=@selector(sendAsynchronousRequest:queue:completionHandler:);
if(![NSURLConnection instanceRespondtoSelector:sendAsyncSelector]){
类\添加方法(对象\获取类([自类]),
sendAsyncSelector,(IMP)sendAsynchronousRequest4,“v@@@@@@@”;
}
}
@结束
#恩迪夫
嘿,Matt,github或类似网站上是否有此代码的版本?如果有这样一个地方,人们可以轻松地提交错误修复和改进,而不是使用实例respondsToSelector
,那就太好了,我们是否应该使用respondsToSelector
?我们正在检查类方法是否存在。RestKit不支持