7

Tôi đang có một khoảng thời gian với thứ gì đó có vẻ như
đơn giản nhưng tôi dường như không hoạt động. Tôi đang xây dựng một ứng dụng iPhone
để truy xuất dữ liệu từ máy chủ lưu trữ web. Tôi đang cố gắng để
thiết lập kết nối không đồng bộ với máy chủ lưu trữ vì tôi muốn giữ thiết bị
được giải phóng trong khi kết nối. (. SendSynchronousRequest đóng băng
điện thoại cho đến khi yêu cầu được thực hiện) Đây là mã của tôi kết nối:Không có dữ liệu được trả lại bằng cách sử dụng NSURLConnection Không đồng bộ

//temp url to see if data is returned: 
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"]; 

NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL 
      cachePolicy:NSURLRequestReloadIgnoringLocalCacheData 
      timeoutInterval:60]; 

/* establish the connection */ 
theConnection = [[NSURLConnection alloc] 
       initWithRequest:dataRequest 
         delegate:self 
       startImmediately:YES]; 

if (theConnection == nil) { 
    NSLog(@"Connection Failure!"); 
    self.urlData = nil; 
} else { 
    self.urlData = [[NSMutableData data] retain]; 
} 

tôi đã tất cả các phương pháp đại biểu thích hợp thiết lập:

-(void)connection:(NSURLConnection *)connection 
     didReceiveResponse:(NSURLResponse*)response 
{ 
    [urlData setLength:0]; 
    UIApplication *application = [UIApplication sharedApplication]; 
    application.networkActivityIndicatorVisible = YES; 
    NSLog(@"Received Response!"); 
} 

-(void)connection:(NSURLConnection *)connection 
     didReceiveData:(NSData*)incrementalData 
{ 
    [self.urlData appendData:incrementalData]; 

    NSNumber *resourceLength = [NSNumber 
       numberWithUnsignedInteger:[self.urlData length]]; 
    NSLog(@"resourceData length: %d", [resourceLength intValue]); 
    NSLog(@"filesize: %d", self.urlDataSize); 
    NSLog(@"float filesize: %f", [self.urlDataSize floatValue]); 
} 

-(void)connectionDidFinishLoading:(NSURLConnection*)connection 
{ 
    NSLog(@"Connection finished loading\n"); 
    NSLog(@"Succeeded! Received %d bytes of data",[urlData length]); 
    _isFinished = YES; 
    UIApplication *application = [UIApplication sharedApplication]; 
    application.networkActivityIndicatorVisible = NO; 
} 

- (void)connection:(NSURLConnection *)connection 
     didFailWithError:(NSError *)error 
{ 
    NSLog(@"Error: %@",[error localizedDescription]); 
} 

Như bạn thấy, tôi đã có một chiếc thuyền tải các thông điệp log vì tôi muốn
để xem nếu bất cứ điều gì đang đến qua cả. Kiểm tra kết nối của tôi
trở lại là TRUE nhưng không có dữ liệu nào được tải. Như tôi đã nói, tôi chắc chắn
Tôi phải đang thực hiện (hoặc không thực hiện) điều gì đó thực sự ngu ngốc. Nhưng cái gì?
Mọi trợ giúp sẽ được đánh giá cao nhất.

Xin cảm ơn, Lawrence

+0

Bạn nên định dạng lại để mã hiển thị chính xác. Thật khó đọc. Sử dụng cú pháp markdown hoặc thậm chí bật wiki cộng đồng để một số người lạ có thể sửa chữa nó cho bạn. – amattn

+0

Thông điệp tường trình nào của bạn thực sự hiển thị? –

+0

Không ai trong số họ hiển thị. –

Trả lời

0

Điều này không trực tiếp trả lời câu hỏi của bạn, nhưng bạn có thể cân nhắc xem thư viện ASIHTTPRequest của Ben Copsey, bao gồm các lớp CFNetwork và bao gồm mã yêu cầu không đồng bộ, có nhiều công việc.

+0

Đó là những gì tôi đã làm. Vì vậy, tôi cho bạn tín dụng. ;-) –

0

Suy nghĩ ban đầu - là đối tượng có tất cả mã này được giữ lại đúng cách? Nó có thể là nó đang được phát hành, và do đó deallocating kết nối ...

Nếu không bạn ít nhất sẽ thấy phản ứng.

+0

Tôi khởi tạo rssData với "nonatomic and retain" trong tệp giao diện .h của tôi. Tôi không nhận được bất cứ điều gì trở lại trên bất kỳ phương pháp đại biểu nào. –

+0

Thêm NSLog vào phương thức dealloc của lớp (cùng lớp với các phương thức đó) để chắc chắn nó không được phát hành ... đó là lời giải thích duy nhất tôi có thể nghĩ đến. Khi tất cả các giải thích khác không thành công, thì bất cứ điều gì còn lại (không có vấn đề như thế nào không thể xảy ra) là sự thật. –

+0

Đó là một gợi ý tuyệt vời. Thật không may, không có gì vẫn đang được trả lại bởi bất kỳ phương pháp đại biểu của tôi. Tôi không hiểu. Nhưng tôi sẽ. –

0

Không có gì rõ ràng là sai ở đó. Tôi có mã giống nhau và hoạt động tốt. Sự khác biệt duy nhất tôi thấy là:

  • tôi sử dụng NSURLRequestUseProtocolCachePolicy thay vì NSURLRequestReloadIgnoringLocalCacheData

  • tôi sử dụng kết nối = [[NSURLConnection alloc] initWithRequest: đại biểu theRequest: tự]; thay vì chỉ định startImmediately: YES (vì đó là mặc định)

Sẽ rất hữu ích nếu bạn biết phương thức đại biểu nào được gọi. Ít nhất, bạn nên nhận được ít nhất một hoặc khác của connectionDidFinishLoading hoặc connectionDidFail được gọi. Nếu không, thì có thể có sự cố với thiết lập đại biểu của bạn - bạn có chắc chắn rằng chữ ký của phương thức ủy nhiệm là đúng hay không và bạn đang chuyển sang đúng mục với tư cách là người được ủy quyền?

+0

Xin chào Mark, Không có phương pháp đại biểu nào của tôi có vẻ được gọi. Tôi xin lỗi vì sự định dạng khủng khiếp của câu hỏi của tôi. Tôi vừa tham gia vào trang web và tôi đã vặn vẹo chú chó con trên trang đó. Tôi đã thử chính sách bộ nhớ đệm giống như bạn sử dụng nhưng không có may mắn. Đây là chữ ký của phương thức của tôi: - (void) connection: (NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response - (void) connection: (NSURLConnection *) connection didReceiveData: (NSData *) data - (void) connectionDidFinishLoading: (NSURLConnection *) kết nối - (void) kết nối: (NSURLConnection *) kết nối didFailWithError: (NSError *) lỗi –

+0

Hmm. Có thể thử bước qua thiết lập trong trình gỡ lỗi và xem liệu có bất kỳ giá trị trung gian nào của bạn không hoạt động không? Thành thật mà nói, có vẻ như phải làm việc ... –

0

Thật khó để không làm bất cứ điều gì vì nó không rõ ràng từ câu hỏi của bạn, nếu có bất kỳ câu lệnh NSLog nào thực thi. Vui lòng hiểu rõ hơn về kết quả bạn đang nhận được.

Từ giao diện nhanh, điều duy nhất trông giống như một vấn đề tiềm ẩn là bạn có điều kiện chủng tộc khi thiết lập kết nối. Nếu mạng đặc biệt nhanh thì có một cơ hội mỏng nhưng không có kết nối: didReceiveData: sẽ được gọi trước khi self.urlData được cấp phát. Tôi khuyên bạn nên phân bổ urlData trước khi bắt đầu kết nối hoặc trong kết nối: didReceiveResponse: để ngăn chặn điều này.

Nếu điều đó không khắc phục được, bạn cần thêm thông tin.

+0

Tôi không nghĩ rằng thực sự có một điều kiện chủng tộc ở đó. Kết nối: didReceiveData: phương thức được gọi trên luồng chính. Trình lắng nghe socket đang chạy trong luồng riêng của nó, nhưng nó gửi thông báo tới runloop của luồng chính. –

+0

Không có câu lệnh NSLog nào của tôi thực sự thực thi. Tôi đang khởi tạo biến rssData trong tệp .h giao diện của tôi. Tôi có nên làm điều đó không? –

0

Bạn nói mã này hoạt động tốt bằng phương pháp không đồng bộ? Kiểm tra URL đó, nó chuyển hướng đến URL khác, vậy điều gì sẽ xảy ra nếu bạn triển khai các phương thức ủy nhiệm chuyển hướng? Điều gì sẽ xảy ra nếu bạn thử một số URL khác nhau?

0

Ứng dụng có phản ứng không? Là runloop chạy? Ứng dụng sẽ làm gì sau khi bắt đầu yêu cầu - nó có trả về từ trình xử lý sự kiện của nó trở lại với runloop không? (Nếu không, bạn sẽ không bao giờ nhận được bất kỳ cuộc gọi lại nào của bạn, bởi vì chúng được phân phối thông qua runloop.)

0

NSURLConnection được thiết kế để hoạt động với bất kỳ loại giao thức nào, không chỉ HTTP. Điều này có nghĩa là kết nối: didFail: withError được gọi cho các lỗi kết nối, nhưng không phải cho các lỗi giao thức. Bạn không kiểm tra lỗi giao thức - bạn phải bắt chúng trong kết nối: didReceiveResponse :. Bí quyết là đối tượng phản hồi được truyền vào thực ra là đối tượng NSHTTPURLResponse. Nếu bạn kiểm tra statusCode của phản ứng, tôi sẽ đặt cược bạn đang nhận được một lỗi HTTP như 404 hoặc 500. máy chủ

1

Một vài gợi ý:

  • Trong đoạn đầu tiên của bạn, thay vì theConnection thử gán đến self.theConnection để đảm bảo các phương thức truy cập thuộc tính được gọi. Ở những nơi khác nhau, bạn cũng trao đổi self.urlDataurlData. Có thể muốn làm cho tất cả chúng nhất quán bằng cách đi qua self.

  • Bạn cũng có thể muốn tạo một thuộc tính dataRequest và đi qua self để đảm bảo rằng nó được giữ lại.

  • self.urlData = [[NSMutableData data] retain]; - bạn không cần phải giữ lại thêm. Đi qua self sẽ giúp bạn. Việc giữ lại thêm sẽ làm cho nó để đối tượng sẽ dính xung quanh và bị rò rỉ ngay cả khi tất cả được thực hiện.

  • Trên ghi chú có liên quan, trong NSLogs của bạn, hãy đảm bảo bạn in số lượng giữ lại cho từng đối tượng. Ngoài ra, bạn có thể muốn có một thói quen làm sạch chung xung quanh để giải phóng các cấu trúc này (hoặc đặt self.foo = nil) vì vậy tại bất kỳ thời điểm nào nếu nó không hoạt động, bạn có thể gọi thường trình để làm sạch mọi thứ.

  • Lấy một bản sao của Charles hoặc WireShark (hoặc chạy tcpdump trong bảng điều khiển) và xem lưu lượng mạng. Nó sẽ giúp xác định ở giai đoạn nào trong luồng mà nó không thành công.

2

Vấn đề là tôi đã tiếp tục lưu chương trình và không dừng lại để cho phép kết nối tải xuống xong. Cảm ơn tất cả các đề xuất.

+0

Tôi có cùng một câu hỏi và tôi không biết ý bạn là gì, bạn có thể giải thích nó không? – remykits

Các vấn đề liên quan