2013-01-17 1 views
0

스토리 보드 및 JSON을 사용하여 느슨한 버전의 LazyTabelImages를 만들려고합니다. 내 주 TableViewController의 ViewDidLoad에서 NSURLConnection을 시작하여 JSON 데이터를 가져 오지만 연결이 완료 될 때까지는 셀이로드되지 않습니다. LazyTableImages와 동일한 동작을 원한다. 셀이 공백으로로드되지만 정보를 채운다. (테이블 데이터를 다시로드한다.) LazyTables가 스토리 보드를 사용하지 않기 때문에 스토리 보드를 사용하지 않으면 복제 할 수 있지만 옵션이 아닙니다.iPhone - NSURLConnection이 완료되기 전에 UITableViewCells가보기로드에 표시되게하십시오.

나는 해결책을 찾기 위해 LazyTableImages를 살펴 봤지만 스토리 보드는 (어쨌든 나에게) 큰 차이를 만듭니다.

셀을 공백으로로드하는 간단한 방법이 있습니까? 예를 들어 기기에 인터넷이없는 경우 TableView를 표시하고 셀에 맞춤 메시지를 추가합니다.

코드 :

나는 연결을 초기화 내있는 viewDidLoad의 일부 ....

NSURLRequest *urlrequest = [NSURLRequest requestWithURL:[NSURL URLWithString:serverURL]]; 
    self.dataConnection = [[NSURLConnection alloc] initWithRequest:urlrequest delegate:self]; 

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

connectionDidFinnishLoading ...

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    //ListData below is an array that my data received (JSON) is loaded into. It is then passed to getTableData. 
    self.dataConnection = nil; 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [self performSelectorOnMainThread:@selector(getTableData:) withObject:ListData waitUntilDone:YES]; 
    }); 
} 

getTableData ...

-(void)getTableData:(NSData *)jsonData 
{ 
    NSError *error = nil; 
    arrayEntries = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error]; 
    for (int x = 0; x < arrayEntries.count; x++) 
    { 
     NSMutableDictionary *dic = [arrayEntries objectAtIndex:x]; 

     //ARecord is a class just like in LazyTableImages that creates objects to keep the icons/data together. The ARecords are loaded into the TableView 
     ARecord *arecord = [[ARecord alloc] init]; 

     NSString *title = [dic objectForKey:@"title"]; 
     NSString *subt = [dic objectForKey:@"subtitle"]; 
     NSString *url = [dic objectForKey:@"image_URL"]; 
     arecord.Icon = nil; 
     arecord.URL = url; 
     arecord.Name = title; 
     arecord.title = subt; 

     //this is where I load an array full of the arecord objects. 
     [array addObject:arecord]; 
    } 
    [self.tableView reloadData]; 
} 
+0

메인 스레드에서 네트워크를 호출 했습니까? 네트워킹 블록 UI 스레드. – jessex

+0

GCD를 사용하여 주 스레드에서 이동하려고했지만 테이블이로드되지 않으므로 흰색 화면 만 표시됩니다. 다른 스레드에서 JSON 구문 분석을 처리하기 위해 NURLConnection에 GCD 호출이 있습니다. – Siriss

+0

NSURLConnection은 이미 비동기 적이어야합니다. 그것을 백그라운드 스레드로 옮기는 것은 나쁜 생각 일 수 있습니다.Quinn이 말했듯이 네트워킹은 "Threads Are Evil ™"과 관련이 있습니다. – jemmons

답변

1

나는 비슷한 것을했습니다. viewDidLoad에서 : 데이터를 다운로드하는 동안 표시하려는 빈 행이 많지만 테이블 데이터의 배열을 [NSNull null]의 몇 가지 개체로 설정합니다. cellForRowAtIndexPath : [self.arrayOfTableData objectAtIndex : indexPath.row] = [NSNull null]인지 확인합니다. 그렇다면 "빈"셀을 반환하고, 그렇지 않으면 셀에 ARRecrod 데이터를로드합니다. 그런 다음 URL이 완료되면 NSNull 배열을 ARR 코드 배열로 바꿉니다.

+0

완벽하게 일했으며 정확히 내가 찾고 있던 것이 었습니다. 고맙습니다! – Siriss

0

난 당신의 코드를 볼 수 없기 때문에, 난 그냥 여기 내 제안을 제공 :

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    dispatch_queue_t queue = dispatch_queue_create(NULL, NULL); 
    dispatch_async(queue, ^{ 

     //add your connection code here 
     //parse the json and store the data 
     // 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      //here to reload your table view again, 
      //since UI related method should run on main thread. 

      [YOUR_TABLEVIEW reloadData]; 

     }); 

    }); 

    [YOUR_TABLEVIEW reloadData]; 
} 

참고 : 스토리 보드에있는 tableview 코드에서 그에 연결되어 있는지 확인하십시오! 희망이 도움이됩니다!

+0

감사합니다. 나는 이것이 내가 필요로하는 접근이었다고 생각하고 있었다. 그러나 나는 아직도 그것을 기울인다. 혼란을 피할 수있는 코드를 추가했습니다. – Siriss

+0

그래서이 방법을 사용해 보았습니다. 그리고 나는 파견 전화를 끊었습니다. 일부 코드를 게시 한 다른 제안 사항이 있습니까? 감사합니다 – Siriss

+0

조심하세요! 스레드에서 네트워킹을하는 것은 거의 항상 실수입니다. – jemmons

1

두 가지 개체로이 작업을 수행합니다. 첫째, 데이터를 비동기 적으로 다운로드하고 완료 될 때 대리인에게 알리는 이미지 가져 오기 클래스가 있습니다. 그런 다음 가져 오기 프로그램의 대리자 메서드를 구현하는 이미지 뷰 클래스가 있습니다. 그래서 뭔가 같은 : 특정에

@implementation MyImageView 

-(id)initWithURL:(NSURL *)aURL andPlaceHolderImage:(UIImage *)aPlaceHolder{ 

    //... 

    [self setImage:aPlaceHolder]; 

    //Note we don't assign this to an ivar or retain it or anything. 
    //That's ok because the NSURLConnection inside the fetcher actually 
    //retains the fetcher itself. So it will live until the connection 
    //terminates -- which is exactly what we want. Thus we disable 
    //CLANG's noisy warnings. 
    #pragma clang diagnostic push 
    #pragma clang diagnostic ignored "-Wunused-value" 
    [[AsyncImageFetcher alloc] initWithURL:aURL andDelegate:self]; 
    #pragma clang diagnostic pop 

    return self; 
} 


-(void)imageFetcher:(MCMAsyncImageFetcher *)anImageFetcher didFetchImage:(UIImage *)anImage{ 
    [self setImage:anImage]; 
} 

@end 

: 그럼 난 UIImageView 또는 UIView 또는 뭔가 서브 클래스

@implementation AsyncImageFetcher 
-(id)initWithURL:(NSURL *)aURL andDelegate:(id<SomeProtocol>)aDelegate{ 

    //... 

    NSURLRequest *req = [NSURLRequest requestWithURL:aURL]; 
    //Note that NSURLConnection retains its delegate until the connection 
    //terminates! See comments in MyImageView below. 
    [NSURLConnection connectionWithRequest:req delegate:self]; 

    //... 
} 

//Implement standard connection delegates here. The important part is: 
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{ 

    // ... 

    UIImage *anImage = [self decodeDownloadedDataIntoAnImage]; 
    if([[self delegate] respondsToSelector:@selector(imageFetcher:didFetchImage:)]){ 
    [[self delegate] imageFetcher:self didFetchImage:anImage]; 
    } 

    //... 
} 

@end 

위임 프로토콜을 구현하고 가져 오기를 해고 (당신이 할 필요가 얼마나 유연성에 따라 다름) 경우 MyImageViewimageView-tableView:cellForRowAtIndexPath:으로 설정하고 해당 자리 표시 자 및 URL에 합리적인 값을 전달하면됩니다.

+0

답해 주셔서 감사합니다. 혼란을 없애기 위해 코드를 추가했습니다. 단지 필요한 것을 얻고 올바르게 편집하는 데 시간이 걸렸습니다. – Siriss

+0

나는이 방법으로 피곤하지만, 지금 내가하는 일은 나의 초기 JSON 호출을 처리하는 데있어 최선의 방법이다. 두 번째 클래스에서 이미지를 얻습니다. 나중에 이미지를 비동기 적으로 가져올 URL이 포함 된 JSON 주먹 비트를 얻는 것입니다. 다른 아이디어? 감사합니다. – Siriss

+0

JSON 비동기 로딩과 동일합니다. 단지'-decodingDowloadedDataIntoAnImage' 대신 다운로드 한 JSON 데이터를 객체로 파싱합니다. 대리자로 이미지를 사용하는 대신 테이블의 컨트롤러를 사용하여 새로운 JSON 데이터를 사용하여 테이블을 다시로드 할 수 있습니다. – jemmons

관련 문제