NSURLConnection connectionDidFinishLoading在其他委托方法有效时不被调用

时间:2014-08-22 12:44:47

标签: delegates nsurlconnection

我尝试使用“Programming IOS 6”一书中的轻量修改示例 我有NSURLConnection的包装类:

@interface WCDHTTPHandler : NSObject<NSURLConnectionDataDelegate>
@property (nonatomic, strong, readonly) NSURLConnection* connection;
@property (nonatomic, strong, readonly) NSData* receivedData;
  - (id) initWithRequest: (NSMutableURLRequest*) req;
  - (void) cancel;
@end

#import "WCDHTTPHandler.h"
@interface WCDHTTPHandler()
@property (nonatomic, strong, readwrite) NSURLConnection* connection;
@property (nonatomic, strong, readwrite) NSMutableURLRequest* request;
@property (nonatomic, strong, readwrite) NSMutableData* mutableReceivedData;
@end

@implementation WCDHTTPHandler

-(NSData*) receivedData {
    return [self.mutableReceivedData copy];
}


- (id) initWithRequest:(NSMutableURLRequest *) req {
    self = [super init];
    if (self) {
        self->_request = [req copy];
        self->_connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
        self->_mutableReceivedData = [NSMutableData new];
    }
    return self;
}


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"Receive HTTP response");
    [self.mutableReceivedData setLength:0];
}


- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"Receive HTTP data");
    //NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    //NSLog(@"%@", result);
    [self.mutableReceivedData appendData:data];
}


- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"Receive HTTP error");
    [[NSNotificationCenter defaultCenter]
        postNotificationName: @"connectionFinished"
        object: self
        userInfo: @{@"error": error}];
}


- (void) connectionDidFinishingLoading:(NSURLConnection *)connection {
    NSLog(@"Finish HTTP loading");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"connectionFinished" object:self];
}


//- (void) connectionDidFinishingDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {
//    NSLog(@"Finish HTTP downloading");
//}


- (void) cancel {
    [self.connection cancel];
    self->_connection = [[NSURLConnection alloc]
                            initWithRequest:self->_request
                            delegate:self
                            startImmediately:NO];
}


@end

我在ApplicationDelegate.m中初始化并使用这个包装器:

@interface WCDAppDelegate()
@property (strong, nonatomic, readwrite) WCDHTTPHandler *httpHandler;
@end

@implementation WCDAppDelegate

NSString *requestString = @"blalblala";
NSData *requestBody = [requestString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest
                                requestWithURL:[NSURL URLWithString:SRV_URL]
                                cachePolicy:NSURLRequestReloadIgnoringCacheData
                                timeoutInterval:15.0];
[request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-type"];
[request setValue:@"utf-8" forHTTPHeaderField:@"Accept-charset"];
[request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody: requestBody];
self.httpHandler = [[WCDHTTPHandler alloc] initWithRequest:request];
[[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:@selector(httpRequestDone:)
    name:@"connectionFinished"
    object:self.httpHandler];
NSLog(@"Start HTTP");
[self.httpHandler.connection start];
return YES;

我将包装器对象设置为属性,因为我担心在执行AppDelegate方法后NSURLConnection可能会失去与其委托的连接,但似乎没有任何意义。

有效。但还不完全。委托回调DidReceiveResponse和DidReceiveData被调用,我从Web服务器接收所有预期的数据。但是没有调用回调connectionDidFinishingLoading。在相关主题中,有人建议计算剩余的数据量,当预期数据长度等于0时,我想在connectionDidFinishingLoading中执行所有操作。但它看起来像一个黑客。

1 个答案:

答案 0 :(得分:0)

您可以使用基于新块的NSURLConnection api,它非常容易实现

    NSURLRequest *request=...;
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

    }];