3

-[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]をiOS <に実装するにはどうすればよいですか?iOS4の実装 - [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, "[email protected]:@@@"); 
    } 
} 

@end 

#endif 

答えて

-1

私はASIHTTPRequest(もはや開発されているが、それでも非常に良い)またはRestKit(私は前にそれを使用していないが、それはまともだ聞いたんき)のように、既に構築されたフレームワークとなるだろう。これらは、OSの異なるバージョン間で同じ機能(非同期のHTTP要求)を提供します。

ifdefsはコンパイル時に実行されているため、プラットフォームごとに別々のバージョンのアプリケーションをコンパイルすることはできません。

実行時に多少の嫌悪感を感じるかもしれませんが、それは価値のある問題よりも難しいようです。

+0

RestKit doesnt support KDaker

0

私は通常、NSOperationのサブクラスを作成し、操作のメインメソッド内で同期要求を行います。操作を呼び出すには、サブクラスのインスタンスを作成し、それをメインスレッドではなくキューにスローします。その後、操作が完了すると、受信したデータでデリゲートを呼び出すか、NSNotificationCenter経由で通知を送信します。

3
// 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, "[email protected]:@@@"); 
    } 
} 

@end 

#endif 
+0

Hey Matt、このコードのバージョンはgithubなどのどこかにありますか?人々がバグの修正と改善を簡単に提出できるどこかに持っているといいでしょう。 'instancesRespondToSelector'の代わりに' respondsToSelector'を使ってはいけませんか? – Andrea

+0

クラスメソッドの存在を確認しています。 – adbie

関連する問題