0

我正在发布到 RESTful 网络服务并接收响应,如果我只取回几条记录,这很好用,但是有一个阈值 didReceiveData: 停止被调用(6 条记录)并且它只是挂起。(不管什么记录,只要数字)

我似乎无法弄清楚为什么。我在 didReceiveResponse 中收到 200 application/json 的状态消息:但这是我从连接中听到的最后一条消息。

从其他客户端,我可以获取包含任意数量记录的完整数据,因此它与我的 NSURLConnection 代码相关。

请参阅下面的完整 NSURLConnection Post 类。

.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

他们

#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;
    }
4

1 回答 1

0

试试这个:</p>

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

因为如果你在 NSDefaultRunLoopMode 中运行连接并且有 UITableView 滚动,它会挂起连接委托。

但是你的问题是不同的。一些服务器会限制来自单个客户端的同时连接数。如果您是这种情况,那么第一个连接将成功,而其他连接将挂起,直到先前的连接完成。

于 2013-06-28T07:35:33.737 回答