2012-07-10 3 views
0

RESTful 웹 서비스에 게시하고 응답을 받으면 일부 레코드 만 다시 가져올 경우이 방법이 유용하지만 didReceiveData : 호출이 중지되는 임계 값 (6 개 레코드)과 그것은 단지 매달린다. (어떤 레코드가 중요하지 않은지, 숫자 만)NSURLConnection 특정 조건에서 멈춤

나는 이유를 알 수없는 것처럼 보입니다. didReceiveResponse에서 200 application/json이라는 상태 메시지가 나타납니다. 그러나 연결에서 마지막으로 들었습니다.

다른 클라이언트에서 모든 레코드가 포함 된 전체 데이터를 얻을 수 있으므로 내 NSURLConnection 코드와 관련이 있습니다.

아래의 전체 NSURLConnection 게시 클래스를 참조하십시오.

.H

#import <Foundation/Foundation.h> 
#import "MBProgressHUD.h" 

@protocol PostJsonDelegate <NSObject, NSURLConnectionDelegate> 
@optional 
- (void) downloadFinished; 
- (void) downloadReceivedData; 
- (void) dataDownloadFailed: (NSString *) reason; 
@end 

@interface PostURLJson : NSObject { 
    NSMutableData *receivedData; 
    int expectedLength; 
    MBProgressHUD *HUD; 
} 

@property (strong, nonatomic) NSMutableData *receivedData; 
@property (weak) id <PostJsonDelegate> delegate; 
@property (assign, nonatomic) int expectedLength; 

+ (id)initWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary withDelegate:(id <PostJsonDelegate>)delegate; 

@end 

하는 .m

#import "PostURLJson.h" 
#define SAFE_PERFORM_WITH_ARG(THE_OBJECT, THE_SELECTOR, THE_ARG) (([THE_OBJECT respondsToSelector:THE_SELECTOR]) ? [THE_OBJECT performSelector:THE_SELECTOR withObject:THE_ARG] : nil) 

@implementation PostURLJson 

@synthesize delegate; 

@synthesize receivedData; 
@synthesize expectedLength; 

+ (id)initWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary withDelegate:(id <PostJsonDelegate>)delegate 
{  
    if (!url) 
    { 
     NSLog(@"Error. No URL"); 
     return nil; 
    } 

    PostURLJson *postJson = [[self alloc] init]; 
    postJson.delegate = delegate; 

    [postJson loadWithURL:url dictionary:dictionary]; 

    return postJson; 
} 

- (void)loadWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary 
{ 
    [self setExpectedLength:0]; 

    receivedData = [[NSMutableData alloc] init]; 

    NSError* error; 

    NSDictionary *tmp = [[NSDictionary alloc] initWithDictionary:dictionary]; 

    NSData *postdata = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&error]; 

    NSString *someString = [[NSString alloc] initWithData:postdata encoding:NSASCIIStringEncoding]; 
    NSLog(@"%@",someString); 

    NSString *postLength = [NSString stringWithFormat:@"%d", [postdata length]]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setTimeoutInterval:10.0f]; 

    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:postdata]; 

    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; 
    [connection start]; 
    [self setLoadingModeEnabled:YES]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response; 
    int errorCode = httpResponse.statusCode; 
    NSString *fileMIMEType = [[httpResponse MIMEType] lowercaseString]; 

    NSLog(@"%d",errorCode); 
    NSLog(@"%@",fileMIMEType); 

    [receivedData setLength:0]; 

    // Check for bad connection 
    expectedLength = [response expectedContentLength]; 
    if (expectedLength == NSURLResponseUnknownLength) 
    { 
     NSString *reason = [NSString stringWithFormat:@"Invalid URL"]; 
     SAFE_PERFORM_WITH_ARG(delegate, @selector(dataDownloadFailed:), reason); 
     [connection cancel]; 
     return; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [receivedData appendData:data]; 
    SAFE_PERFORM_WITH_ARG(delegate, @selector(downloadReceivedData), nil); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    SAFE_PERFORM_WITH_ARG(delegate, @selector(downloadFinished), nil); 
    [self setLoadingModeEnabled:NO]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog(@"Something went wrong..."); 
    HUD.labelText = @"Something went wrong..."; 
    [self performSelector:@selector(didFailHideHud) withObject:nil afterDelay:2]; 
} 

- (void)setLoadingModeEnabled:(BOOL)isLoading 
{ 
    //when network action, toggle network indicator and activity indicator 
    if (isLoading) { 
     [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

     UIWindow *window = [UIApplication sharedApplication].keyWindow; 
     HUD = [[MBProgressHUD alloc] initWithWindow:window]; 
     [window addSubview:HUD]; 
     HUD.labelText = @"Loading"; 
     [HUD show:YES]; 
    } else { 
     [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

     [HUD hide:YES]; 
     [HUD removeFromSuperview]; 
    } 

} 

-(void)didFailHideHud 
{ 
    [HUD hide:YES]; 
    [HUD removeFromSuperview]; 
} 

@end 

편집 서버 내가 잘못 그래서이었다 로그인하지 않은 NSURLResponseUnknownLength을 유발 특정 크기 후 유효한 길이를 환원되지 콘솔에 "잘못된 URL"메시지가 표시되지 않습니다.

if (expectedLength == NSURLResponseUnknownLength) 
    { 
     NSString *reason = [NSString stringWithFormat:@"Invalid URL"]; 
     SAFE_PERFORM_WITH_ARG(delegate, @selector(dataDownloadFailed:), reason); 
     [connection cancel]; 
     return; 
    } 
+0

일반적인 제한 시간 간격은 약 60 초이며, 시간을 늘리면 어떻게됩니까? –

+0

같은 문제는 사실이 짧은 시간 제한을 설정하여이 문제를 디버깅하려고했습니다. – KDM

+0

connectionDidFinishLoading 또는 didFailWithError에 도달 했습니까? – Aymarick

답변

0

이 시도 : 당신이 NSDefaultRunLoopMode에서 연결을 실행하고 jQuery과 스크롤이있는 경우

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 
[connection start]; 

, 그것은 연결 대리자를 중단됩니다 때문입니다.

그러나 문제는 다릅니다. 일부 서버는 단일 클라이언트의 동시 연결 수를 제한합니다. 이 경우에는 첫 번째 연결이 성공하고 다른 연결은 이전 연결이 완료 될 때까지 중단됩니다.

관련 문제