오늘의 주제

1. 이미지 웹에서 로딩하기 
2. 테이블 뷰 섹션 이름 넣기



서른 아홉번째 시간입니다.^^

지난 번에는 스레드 관리와 네트워크 상태 감지까지 해 보았습니다.
잘 실행 되시나요?
혹여나 부족한 부분이 있다면 꼭 댓글주세요~!

오늘은 이미지를 웹에서 로딩해서 테이블 뷰에 넣어주고, 테이블 뷰에 섹션 이름 넣는 것 까지 해보려 합니다.

우리가 이미 만들어 놓은 것들이 많으니 소스를 조금만 추가하면 될거예요~

자~! 출발!


# 웹 이미지 로드

우리는 지난 번에 item을 불러올 때 책 이미지에 대한 URL을 함께 받아왔습니다.
네, 이렇게 서버에서 정보가 내려올 때, 이미지 데이터를 직접 보내주지 않고 이미지의 주소를 보내줍니다.
혹여 이미지가 필요하면 받아가라~ 그런 뜻이겠죠 ㅎ
그래서 이미지를 불러와서 이미지 데이터를 각 item dictionary에 넣어주는 작업을 합니다.
item dictionary에 이미지를 넣어주고, 아래 테이블뷰 데이터소스 메소드에서 item 내부의 데이터를 불러와서 테이블뷰에 나타내게 되므로, 우리는 이 스레드에서 데이터를 딕셔너리에 넣어주기만 하면 되는거예요~ 플로우를 잘 이해해 보시기 바랍니다 ㅎ

또한, 지난 번에 제가 실수 한 부분중에 우리가 실행하고 있는 검색 스레드에서 테이블뷰의 데이터를 reload하는 부분이 있었는데요, 이는 잘못된 것이고 메인 스레드에서 변경해 주어야 하는 것이 맞습니다. 그래서 그에 관한 부분을 수정했습니다.


그리고 이제 위에서 말씀드린대로 데이터소스 메소드인 cellForRowAtIndexPath 메소드로 와서 이미지도 불러와서 셀에 넣어주는 코드를 넣어줍니다.


그리고 이번엔 책 말고 동영상도 로드해와 볼게요~ 
그런데 제가 작업하다 보니 지난번에 복사-붙여넣기 신공으로 코드를 작성하다 보니 오타낸 부분이 있더라구요 ㅎ
찾아서 이렇게 다시 바꿔주세용 ㅎ 


자, 그리고 이제 아까 책 이미지 데이터를 가져온 것과 마찬가지로 동영상 썸네일 이미지도 가져와 보겠습니다.
책 이미지 URL은 받아온 item 에서 'coverImage'라는 키값으로 찾을 수 있었는데, 여기서는 키값이 'thumbnail'로 되어있네요.
자세한 사항은 다음 오픈 API 의 동영상 검색 섹션을 참고하세요 ㅎㅎ
그런데 우리가 데이터 소스 메소드에 작성했을 때, 이미지를 꺼내오는 키워드는 'coverImage'였으므로 여기서도 item 딕셔너리에 넣어줄 때에는 'coverImage'라는 키로 넣어주었습니다.


이제 준비가 끝났으니 호출해 주어야 겠죠?ㅎ 책 검색 스레드를 만들어 준 것 같이 동영상 검색 스레드도 만들어 줍니다.


텍스트를 변화시킬때와 검색 버튼을 눌렀을 때 모두 해야 하므로 두 번 이렇게 생성해 주죠 ㅎ 
생각해 보니 이것도 따로 메소드로 만들어서 빼주는게 좋겠네요~^^


자, 그리고 실행해 봅니다~
그런데 두 가지 정보를 모두 가져왔는데, 어디가 어디껀지 구분이 잘 안가네요 +_+
섹션 헤더에 이름을 넣어서 구분을 지어보도록 합시다~



# 테이블 뷰 섹션 제목 달기

자, 이렇게 테이블뷰 델리게이트 메소드를 하나 더 작성해 줍니다.
책 검색 결과 섹션에는 Book이라는 제목을, 동영상 검색 결과 섹션에는 Video라는 제목을 넣어주었습니다~ 


짜잔~ 검색 해보시면 이런식으로 이쁘게 섹션이 구분되어지네요 ㅎ



그런데 제가 막 스크롤을 해 보던중 이상한 현상이 생겼어요 +_+
분명히 이미지가 들어가 있지 말아야 할 cell에 이미지가 박혀있는거예요 ㅎ


데이터소스에서 불러들일때 제대로 nil처리를 해주지 않아서 생기는 현상이예요 ㅎ
조건을 확인하고 검사해서 원치않는 다른 cell의 내용을 가져오지 않도록 처리해 줍니다.
왜 이런 현상이 발생하는지는 하아... 내용이 너무 길어져서... +_+
일단 cell을 만들 때 이런것에 주의해야 한다는 점 잊지 말아주세용~



이렇게 깔끔하게 처리해 주면 더이상 원치 않는 화면이 나타나는 것을 막을 수 있습니다~


자... 이렇게 오늘도 또 하나 해 보았네요~

포스팅이 점점 길어지고 있어요~ 할 내용들이 정말 많네용 ㅋ

이 모든 내용들을 따로따로 분리해서 할까도 생각해 보았지만 이렇게 묶어서 하나의 프로젝트로 진행하는 것이 실전 감각에 도움이 되실거라 생각하여 이렇게 진행해 보았습니다~

질문사항이나 요청사항 있으시면 댓글주세요~^^*

by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 



Posted by yagom

댓글을 달아 주세요

  1. lss 2012.06.19 11:38  댓글주소  수정/삭제  댓글쓰기

    안녕핫에ㅛ 강좌잘보고있습니다. 한가지 질문이있습니다.
    서치바와서치디스플레이컨트롤러를 동시사용할대요 서치바에 단어입력하잖아요...근데 입력할때마다
    검색해서뿌려주는데요 그렇게하지않고 다입력후 버튼을 눌렀을때 뿌려주고싶은데요...
    1.일단 단어입력때마다 검색하지않게하려면 어떻게해야하는지요?
    2.서치버튼눌렀을때 어떤메소드로 테이블뷰를 로드하는지요? UISearchDisplayController에도 reloaddata라는 함수가있긴한데 잘동작하지않네요

    • Favicon of https://blog.yagom.net BlogIcon yagom 2012.06.19 13:13 신고  댓글주소  수정/삭제

      1.
      http://blog.yagom.net/270
      iOS개발하기 #36. UISearchDisplayController(2) <UISearchBar, NSThread, JSON, NSRequest>
      의 내용을 보면 맨 처음에 나옵니다... :-)
      델리게이트에 보면 searchBar:textDidChange:
      라는 델리게이트 메소드가 있구요, searchBarSearchButtonClicked: 라는 메소드가 있네요.
      위의 메소드가 메소드명 처럼 글이 변경될 때 호출되는 델리게이트 메소드구요, 아래 것이 서치 버튼을 눌렀을 때 호출되는 델리게이트 메소드입니다.
      참고하시면 될 것 같구요...

      2.
      1번에 답변 된 내용에 포함되는 것 같네요.
      테이블 데이터를 다시 로드하려면
      [[searchDisplayController searchResultTableView] reloadData]; 라고 다시 로드하시면 됩니다.

      처음부터 차근차근 다시 읽어보세요...^^*
      충분한 정보가 될 것이라 생각합니다~
      또한 이 내용을 잘 이해하시려면 delegate와 dataSource에 대한 이해서 먼저 필요로 합니다. :-)

      좋은 정보 얻어가셨으면 좋겠네요~

  2. Have 2012.06.19 11:49  댓글주소  수정/삭제  댓글쓰기

    첫번째 screenshot 바로 아래 단락에 말ㅆ므 라는 오타가 ! ㅎㅎ

  3. ㅠㅠ 2012.06.26 18:52  댓글주소  수정/삭제  댓글쓰기

    //request 정보를 담은 딕셔너리 생성
    NSDictionary *videoRequestDic = [[NSDictionary alloc]initWithObjectsAndKeys:
    [searchBar text],@"key",
    @"video",@"requestKind",
    [NSNumber numberWithInt:1],@"pageNum",
    nil];
    [self readyForRequestWithDictionary:videoRequestDic];
    이부분을 넣으면 잘검색이 되는데 넣으면

    2012-06-26 18:52:09.922 SearchBar[4496:707] Reachability Flag Status: -R -----l- networkStatusForFlags
    2012-06-26 18:52:12.506 SearchBar[4496:6707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
    *** First throw call stack:
    (0x3763a88f 0x3533f259 0x3763a789 0x3763a7ab 0x37f065b3 0xb7153 0x37e20a81 0x37eb4591 0x33eaf735 0x33eaf5f0)
    terminate called throwing an exception(lldb)

    이런 로그가 뜨네요 ㅠㅠ

    • Favicon of https://blog.yagom.net BlogIcon yagom 2012.06.26 23:44 신고  댓글주소  수정/삭제

      안녕하세요 :-)
      현재 로그만으로 본다면 어디선가 전달값이 nil이라는 메세지가 나오네요...
      어디선가 데이터를 넘겨줄 때 nil값이 넘어오면 Exception을 발생시키고 뻗어버리는 메소드 들이 있습니다.
      의심이 가는 부분의 데이터들을 로그로 찍어보시고 nil값이 나오는 녀석을 찾아서 수정해 주시면 될 것 같습니다 ^^*

    • ㅠㅠ 2012.06.27 11:18  댓글주소  수정/삭제

      감사합니다. 찾아보겠습니다.

      항상 잘보고있습니다. 아직은 모르는부분이 많지만 많은 도움을 받아갑니다.

    • Favicon of https://blog.yagom.net BlogIcon yagom 2012.06.27 11:47 신고  댓글주소  수정/삭제

      네 :-) 찾게 되시면 어디서 어떤 실수가 있었는지도 알려주시면 좋겠습니다.
      고맙습니다 ^^*
      자주자주 놀러오세요 ㅎ

  4. ㅠㅠ 2012.07.02 10:38  댓글주소  수정/삭제  댓글쓰기

    xml 설명하신거 보는동안 리플이 달려있었네요 ㅎㅎ
    해답을 찾았습니다.
    URL생성에서
    NSURL *url = nil;
    if([kindOfSearch isEqualToString:@"book"]){
    url = [NSURL URLWithString:@"http://apis.daum.net/search/book"];
    }else {
    url = [NSURL URLWithString:@"http://apis.daum.net/search/vclip"];
    }
    비디오 검색 URL생성이 빠져있어서 생성을 했더니 잘나옵니다.

    많은 도움이 됐습니다!

  5. Sio 2012.07.24 14:43  댓글주소  수정/삭제  댓글쓰기

    혼자 오타내고 에러나고 찾느라 삽질하고 ㅋㅋㅋㅋ
    그래도 어찌어찌 실행은 되었네요 ㅜㅜ ㅎㅎㅎㅎ

    잘보고갑니다~!

  6. 나에게넌 2012.08.14 11:02  댓글주소  수정/삭제  댓글쓰기

    동영상 thumbnail 가져와서 테이블에 뿌려주는 부분..필요한 부분이었는데..완전 감사합니다..
    오늘도 계속 흡입흡입..

  7. 컴맹 2012.09.12 04:37  댓글주소  수정/삭제  댓글쓰기

    워낙 강의를 잘해주셔서 UISearchDisplayController 5강좌를 다 보는동안 막힌적이 없었네요.^^
    좋은 강의 감사합니다.^^

  8. MHY 2012.09.20 10:31  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 네이버카페에서 YAGOM님 강좌글을 보고 오게 되었습니다.
    작성하신 글들을 보면서 공부하고 있는데 현재 내용중에 궁금한게 있어서 혹시 이글을 보신다면
    도움을 받고 싶습니다.

    위내용으로 제이슨으로 받은 내용을 테이블뷰에 표시되는것 까진 해보았는데 테이블뷰에서 셀을 선택했을때
    해당 내용을 세부적으로 보여줄수 있는 세부뷰를 만든다면 어떻게 해야 하나여..
    데이터 배열을 해서 표시하는것은 해보았는데 이부분을 어떻게 해야하는지 모르겠습니다.
    도움 부탁드립니다.

    • Favicon of https://blog.yagom.net BlogIcon yagom 2012.10.03 21:45 신고  댓글주소  수정/삭제

      그것은 테이블 뷰 델리게이트 메소드를 찾아보시면 나올거예요~
      지금 메소드 이름이 정확하게 기억이 나지 않지만...
      selectRow가 들어가겠죠?ㅎ

  9. 귀공자 2012.10.09 10:45  댓글주소  수정/삭제  댓글쓰기


    아 에러의 원인을 찾았네요..

    제가 강의 내용을 다시 훑어 보았는데



    -(void)requestSearch:(NSDictionary *)requestDic{
    }
    ....

    함수에서


    NSURL *url = nil;
    if([kindOfSearch isEqualToString:@"book"]){
    url = [NSURL URLWithString:@"http://apis.daum.net/search/book"];
    }else {
    url = [NSURL URLWithString:@"http://apis.daum.net/search/vclip"];
    }
    란 부분을 넣어 주셔야 할 것 같습니다.
    이런 부분의 언급이 없는 것 같습니다.




  10. 한소쿠리더하기 2013.02.01 00:44  댓글주소  수정/삭제  댓글쓰기

    다 구현하고 난뒤에 검색어를 입력하면서 간혹 검색어에 따라 에러가 나는 경우가 있습니다.
    Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 15 beyond bounds for empty array'
    같은 에러가 나는데...

    혹시 검색어가 입력되는 과정에서 텍스트가 달라질때 마다 처리되는 메소드에서 입력될때마다 받아오는 어레이가 달라지면서 딜레이가 걸린 이전에 처리하던 작업이 달라진 어레이에 대입된다던가 하는 경우도 있나요?

    예를 들어서 iphok를 입력할때, ipho까지 입력했을 때 결과가 100개인 어레이여서 for 문이 0에서 99까지 돌아가고 있는데 iphok가 되는 순간 결과가 더 적은 어레이로 바뀌면서 objectAtIndex:i에서 대입하는 어레이에 없는 인덱스에 대입이 되는 종류가 아닐까 싶기도 하고...

    같은 검색어를 입력해도 인디케이터가 다 돌아갈때까지 기다렸다가 한글자씩 천천히 입력하면 에러가 안나는데 빠르게 입력하면 저 에러가 종종 일어나는 것 같고. 에러가 났다 안났다 하니 원인을 알수가 없습니다.

    이미지를 어레이에 넣는 부분을 막으면 에러가 안나구요.

    일단 이미지가 nil이 아니면 이미지를 어레이에 추가하는 부분에
    if (i >= [videoItemArr count]) {
    break;
    }
    와 같이 i가 갯수보다 크거나 같으면 멈추게 하게 하겠다고 이거 넣고 나서는 오류가 안나긴 하는데...

    실제로 제가 예상한 것과 같은 일이 생길수도 있나요? 아님 다른 이유가 있을까요?

    • Favicon of https://blog.yagom.net BlogIcon yagom 2013.02.01 12:58 신고  댓글주소  수정/삭제

      아무래도 말 그대로 튜토리얼이기 때문에 완벽할 순 없습니다...ㅎ
      말씀하신 내용도 충분히 발생할 수 있는 여지가 많습니다 ^^;

  11. Favicon of https://gogodao.tistory.com BlogIcon rustyDAO 2013.02.18 16:59 신고  댓글주소  수정/삭제  댓글쓰기

    하 ~ 완벽해요 @.@ 완벽해 ㅠㅠ
    ㅋㅋ 갈수록 눈이 트이네요 ^.^

    url설정하는거 video따로 안해준거는 윗분들이 이미 댓글 다셨네요 ㅋㅋ 반년전에 ㅋㅋㅋ

    야곰님 빨리 쾌유하세요 ^^

  12. dklee7206 2013.07.10 16:15  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~ 강의 잘 보고 있습니다. 중간 중간 따라하다 막히는 부분이 있어서요..
    혹시 강의 자료 소스코드 메일로 보내주실수 있을까요?
    dklee7206@naver.com 입니다.

    앞으로 왔다 갔다 하다가 흐름이 끊겨서요.. 틀린거 있는지 체크해보려구요..

    감사합니다.

  13. djsa 2016.04.17 12:24  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.강좌 잘 보고있습니다. api요청에서 NSURLConnection 이게 잘 안되더군요.ㅠ.ㅠ
    그래서 session으로 했는데 오류 뜨네요.
    제 다른 건 다 같고 http 요청 보내는 걸 이렇게 썼습니다.

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *defaultSession =[NSURLSession sessionWithConfiguration:defaultConfigObject];
    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response, NSError *error){
    NSLog(@"Response:%@ %@\n",response, error);
    if(error== nil){

    NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"Data = %@", text);
    NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

    NSLog(@"result:%@",resultDic);

    if([kindofSearch isEqualToString:@"book"])
    bookSearchThread = nil;
    else
    videoSearchThread = nil;


    }
    }];
    [dataTask resume];
    근데 로그에 이렇게 남습니다
    2016-04-16 20:11:25.123 GoogleMap[2608:647075] Percent
    2016-04-16 20:11:25.129 GoogleMap[2608:647931] Response:(null) Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x7fadcbf04340 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}, NSErrorFailingURLStringKey=http://apis.daum.net/search/book, NSErrorFailingURLKey=http://apis.daum.net/search/book, NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.}

    제가 뭐 잘못했는지 도무지 모르겠습니다.

    • Favicon of https://blog.yagom.net BlogIcon yagom 2016.04.26 22:41 신고  댓글주소  수정/삭제

      안녕하세요 :)
      답변이 늦어 죄송합니다.
      구글에 iOS 9 secure connection이라고 관련 검색을 하시면 관련 내용을 찾아보실 수 있을 거예요 :)