2013-09-22 44 views
0

我有一個NSURLConnection非常令人費解的問題。它正在返回另一個線程或其他東西中的數據,事情不按照正確的順序工作。我應該接收json數據然後解析它,但是在解析器失敗後實際上正在接收數據。這是日誌。NSURLConnection數據檢索

2013-09-22 14:44:40.454 WebServiceExample[39306:a0b] Parsing Error: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (No value.) UserInfo=0xa0b47e0 {NSDebugDescription=No value.} 2013-09-22 14:44:41.312 WebServiceExample[39306:a0b] Succeeded! Received 112 bytes of data

我正在做一個小的框架,以減輕我的生命連接到軌道API,我稱它的目標軌道或,但我已經花了整個週末,試圖找出我做錯了什麼。下面的代碼:

@interface ORObject : NSObject 

@property (nonatomic, retain) NSMutableDictionary *properties; 
@property (nonatomic, retain) ORWebManager *webManager; 
@property (nonatomic, retain) NSString *route; 
@property (nonatomic, retain) NSString *singularClassName; 

- (id) initWithRoute:(NSString *) route webManager:(ORWebManager *) webManager; 
- (id) initWithRoute:(NSString *) route; 
- (ORObject *) find:(NSInteger) identifier; 
@end 

這裏被發現的實現:

- (ORObject *) find:(NSInteger) identifier 
{ 

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%ld.%@", [ ORConfig sharedInstance].baseURL, self.route, (long)identifier, self.webManager. parser.contentType]]; 

    ORObject *object = [self.webManager httpGet:url]; 

    if (object) { 
     object.route = self.route; 
     object.webManager = self.webManager; 
    } 

    return object; 
} 

這裏是ORWebManager類

- (ORObject *) httpGet:(NSURL *)url 
{ 
    ORGetRequester *requester = [[ORGetRequester alloc] init]; 
    NSMutableData *data = [requester request:url]; 
    return [self.parser toObject:data]; 
} 

ORGetRequester的超類是ORHTTPRequester的HTTPGET方法和它實現NSURLConnectionDelegate協議方法

@interface ORHTTPRequester : NSObject<NSURLConnectionDelegate> 
@property (nonatomic, retain) NSMutableData *receivedData; 
@property (nonatomic, retain) NSMutableURLRequest *req; 
@property (nonatomic, retain) NSURLConnection *connection; 
@end 

@implementation ORHTTPRequester 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse 
    [self.receivedData setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [self.receivedData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection 
    didFailWithError:(NSError *)error 
{ 
    NSLog(@"Connection failed! Error - %@ %@", 
      [error localizedDescription], 
      [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSLog(@"Succeeded! Received %d bytes of data",[self.receivedData length]); 
} 
@end 

最後這裏是ORGetRequester,這是「魔法」發生的地方。立即

@interface ORGetRequester : ORHTTPRequester 
- (NSMutableData *) request:(NSURL *)url; 
@end 

@implementation ORGetRequester 
- (NSMutableData *) request:(NSURL *)url 
{ 
    self.req = [NSMutableURLRequest requestWithURL:url 
               cachePolicy:NSURLRequestUseProtocolCachePol icy 
              timeoutInterval:60.0]; 
    self.receivedData = [[NSMutableData alloc] init]; 
    self.connection = [[NSURLConnection alloc] initWithRequest:self.req delegate:self]; 

    if (!self.connection) { 
     NSLog(@"Connection Failed"); 
    } 

    return self.receivedData; 
} 
@end 

回答

1
self.connection = [[NSURLConnection alloc] initWithRequest:self.req delegate:self]; 

回報,因爲它開始的異步操作。當調用connectionDidFinishLoading:時,您需要解析數據。

或考慮使用:

+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler 

的HTTP操作完成時完成塊將被調用。處理完成塊中的數據並通知任何需要數據的對象。如果您不需要其他委託方法,這可能是一個很好的選擇。

+0

現在我正在考慮它,實際上沒有辦法做一個ActiveRecord-ish API,它需要是同步的,這不好。我想簡化一些東西,並且沒有一個擁有一百萬個方法的臃腫的ViewController,但它看起來像是iOS異步處理HTTP請求的方式。我必須重新設計這整個Objective Rails的東西。非常感謝您的幫助@Zaph,非常感謝。 *編輯*只記得觀察者模式,這可能是我需要的:) –