본문 바로가기

about DEV/just follow

iOS 개발 무작정 따라하기 - Address Book 9

일주일만에 다음 연재를 포스팅합니다.  역시 평일은 시간이 도통 나질 않네요.
어쨌든, 지난 시간에는 Group이라는 객체를 만들고 해당 객체의 속성값들을 입력하는 부분까지 진행했습니다. 오늘은 예외처리를 진행하도록 하죠.

사용자가 입력한 정보값들을 저장하는 부분을 진행중이다.  이 저장이라는것이 단순하게 생각하면 그냥 저장 끝 할 수 있겠지만, 최대한 사용에 필요한 예외처리들까지는 함께 처리하도록 하겠다. 

일단, 그룹타이틀의 경우 입력되지 않으면 다음으로 진행이 되지않도록 되어있다. 이 부분은 필수부분인지라 이대로 유지는 하고, 그룹 대표이미지와 태그 그리고 메모데이터는 상황에 맞춰서 예외처리를 하도록 하겠다.  아무런 데이터값이 없는데 그냥 무턱대고 저장을 해버리면 원치않은 결과물과 에러가 발생할 수 있기 때문이다.  대략의 순서를 설명하자면, 아래와 같다.

1. 그룹타이틀이 입력될 경우 저장프로세스가 실행된다. 
2. 그룹 대표이미지를 지정했는지 검색한다.  그룹대표이미지가 있을 경우에만 저장하게 할 것이다.
3. 그룹 태그가 입력되었는지 검사한다. 
4. 그룹 메모가 입력되었는지 검사한다.
5. 정상적으로 모든 필드(Field)가 입력되었으면 모두 저장을 할 것이고, 그렇지 않을 경우, 입력한 데이터만 DB에 저장하는 순서를 거칠 것이다.

자 그럼 시작해보자.


- 그룹 대표이미지/태그/메모가 존재하는지 검사하자.



tmpGroupImage라는 UIImage를 만든다.  해당 객체는 groupPictureBtn의 이미지속성을 가져온다.  그 후에, tmpGroupImage가 UIImage Class인지 확인한다.  [beforeObject isKindOfClass:[afterObject class]] 라는 것은, beforeObject의 클래스가 afterObject의 클래스와 동일한지 검사하는 코드다.  앞으로 간간히 보게 될 코드니깐 숙지하도록 한다.

풀이하자면 "만약 tmpGroupImage의 클래스가 UIImage 클래스라면," 이라고 해석할 수 있다.  어쨌든, 이미지객체가 존재한다면, Group Object의 image에 해당 객체를 입력한다.


위 스크린샷을 참고해서 코드를 추가하도록 하자.
주석을 참고해보면 해당 코드들이 어떤 역활을 하는지 쉽게 이해할 수 있을 것이다.

여기까지 진행해봤다면 빌드/런을 실행해서 어떤 결과가 나오는지 확인하도록 하자.
참고로 아직까지 시뮬레이터에서의 결과는 달라지는 것이 없을 것이다. 기존과 달라진 점이 있다면, 여러분이 태그나 메모에 데이터를 입력하지 않았다면, Group 객체의 해당 데이터에 입력하지 않는 다는 것이다. 이것만 기억하자.  [데이터가 입력되지않았다면, 불필요하게 저장할 필요가 없다] 


- 그룹 대표이미지를 정해야지?


이제 이미지를 설정하는 부분을 진행한다.  
Apple은 기본적으로 UIImagePickerControllerDelegate 메서드를 제공해서 개발자로 하여금 손쉽게, Device의 카메라나 포토라이브러리에 접근을 할 수 있게 했다.  일단 해당 버튼에 액션 메서드를 붙혀보도록 하자.


AddGroupViewController.h에 -(IBAction)touchPictureBtn:(id)sender; 라는 메서드를 선언한다.



그 후에 AddGroupViewController.m 파일에 해당 메서드의 구현부를 입력한 후에,
AddGroupViewController.xib에서 위 스크린샷을 참고해서 Outlet Action을 연결시키도록 하자. 시뮬레이터에서 [그룹이미지선택] 버튼을 클릭하면, 해당 메서드가 호출된다.


Xib까지 수정했다면, 다시 AddGroupViewController.h 파일로 돌아가자.

UIImagePickerControllerDelegate의 Methods들을 사용하기 위해서는 헤더파일에 위와 같은 선언이 필요하다. 쉽게 생각하면, 해당 클래스에서 UIImagePickerControllerDelegate Methods를 사용할 수 있으니깐..알아둬! 라고 선언하는 것과 같다. 또한, UIImagePickerControllerDelegate를 사용하기 위해서는 UINavigationControllerDelegate 도 함께 선언해야 한다. 

위 스크린샷을 참고해서 코드를 추가한다. 

이제 델리게이트까지 선언했다면 구현부분에 코드를 추가하자.


일단 버튼을 클릭했을때 예외처리가 필요하다. 
iOS Device들 중에, 카메라가 포함되어있는 기기가 있는 반면 그렇지 않은 기기도 있기 때문이다.  우리가 현재 사용하고 있는 iOS Simulator 의 경우에도 카메라가 없는 것으로 인식된다.  위 스크린샷을 참고해서 코드를 추가하도록 한다.

여기서 또 처음 보는 것을 보게 된다. 바로 UIActionSheet라는 녀석인데, 이건 지난시간에 사용되었던 UIAlertView와 비슷한 일을 수행한다. 단지 보이기에 다를 뿐이다.  물론 AlertView와는 그 사용을 달리한다. 어쨌든, 여기까지 진행했다면, 빌드/런을 실행해서 어떤 결과가 나오는지 확인해보도록 하자.


바로 이렇게 생긴 시트가 올라온다. 어디서 많이 봤을 것이다. iOS에서 지원하는 기본 객체이면서 그 활용성이 굉장히 많은 녀석이다.  어쨌든, 나오긴 나왔는데, 코드상에서 보기싫은(?) 노란 라인으로 Warning이 출력된다. 

풀이하자면 이거다. "너 UIActionSheet 쓰려면 Delegate 선언해야하는데 왜 안하니?" 라는 것이다.
UIAlertView도 마찬가지로 Delegate를 선언했었는데, 액션시트도 이와 같다.  헤더파일로 가서 델리게이트를 선언해주도록 하자. 


자 위 스크린샷처럼 헤더파일에 UIActionSheetDelegate 를 선언하니, .m 파일에서 아까같은 노란 Warning 메세지가 사라졌다.  이제 액션에 따른 기능을 구현해야한다.  일단 우리는 Simulator에서만 확인하기 때문에 시뮬레이터 위주로 코드를 작성할 것이다.  다시 AddGroupViewController.m 파일로 돌아가자.


UIActionSheet Delegate Methods는 위와 같다. 이중에서 우린 clickedButtonIndex로 끝나는 메서드를 이용할 것이다.  액션시트의 버튼을 클릭할때 실행되는 델리게이트 메서드다. 


해당 메서드가 정상적으로 실행되는지 확인해보록 하자. actionSheet를 로드한 후에, 아무 버튼을 클릭해보면 위 스크린샷처럼 작성해둔 Log가 출력된다.  그리고 그 밖의 delegate methods들이 언제 실행되는지는 직접 코드를 작성해보기 바란다. 


이번엔 코드가 조금 길다. 위 스크린샷을 참고하도록 하자. 각 라인별로 주석을 달아두었으니, 이해하기 어렵진 않을 것이다.  참고로 setAllowsEditing은 YES로 설정했다. 왜냐면, 그룹대표이미지의 버튼이 정사각형 사이즈이기 때문이다. 


이제 빌드/런을 통해 우리가 지금까지 작업했던 것을 확인해보도록 하자. 


사진첩에서 고르기 버튼을 클릭하면, 위와 같은 결과물이 나타난다.
어라? 그런데 No Photos라는 안내문이 딱! 나타나네? 당연하다. 시뮬레이터 내의 포토라이브러리는 현재 비어있는 상태이기 때문이다.  테스트를 하기 위해서는 포토라이브러리 내에 이미지가 있어야하기 때문에, 이미지를 임의로 저장해보도록 하자.


시뮬레이터의 Home버튼을 누른 후에, Safari를 실행해보도록 하자.


열린 사파리에서 주소를 imonis.net을 입력하고 GO버튼을 누르자. 





필자의 블로그내에서 아무 포스팅을 클릭해서, 해당 포스터 내에서 이미지 위에 커서를 댄 후에, 마우스버튼을 꾹 누르고 있는다.  그럼, ActionSheet가 출력되는데 그 중에, Save Image버튼을 클릭한다.  그리고 다시 우리가 만들고 있는 AddressBook을 실행해보면, 위 스크린샷과 같은 결과물을 확인할 수 있을 것이다.

일단 테스트로 임의의 이미지가 필요하기 때문에 아무 이미지면 된다. 


어쨌든 포토선택창에서 조금 전에 저장해둔 이미지를 선택해서 확인해보면 위 스크린샷결과물이 나올 것이다.  우리가 setAllowsEditing을 YES로 설정했기 때문에, 정사각형 모양대로 잘라서 불러올 수 있다. 원하는 대로 에디트를 완료한 후에, Choose버튼을 클릭해보자. 

그러면 아직 아무런 변경이 없을 것이다.  왜냐면, UIPickerController Delegate methods를 이용하지 않았기 때문이다. 선택된 이미지를 가져온 후에, 처리를 해줘야한다. 


이제 ImagePickerController Delegate 메서드를 구현해보자.
위 스크린샷을 참고해서 코드를 추가한다.
info의 데이터중에 이미지를 가져온 후에, 해당 이미지를 groupPictureBtn의 이미지로 사용한다. 그 후에, Modal로 띄운 PickerViewController를 내려준다.


결과가 어떻게 나오는지 확인해보자. 우리가 선택하고 편집(정사각형대로)한 이미지가 Group의 대표이미지가 되어있음을 확인할 수가 있다.  오늘은 참 진도 많이 나갔네.. 너님들 어때요? 하나도 안어렵죠? 

자 이제, 본격 저장을 해보도록 하자.  계속 저장한다 한다 하면서 아직도 안하고 있는....
하지만 여러분도 알다시피, 저장을 하기에 앞서 데이터 입력부분과 예외처리 등으로 인해 제법 많은 포스트들을 할애했다는 것을 알아주길 바란다. 




AddGroupViewController.h 에 -(void)addGroup:(Group *)group; 메서드부터 선언하도록 하자. 
우리는 Group 이라는 객체를 만들었고, 적절한 예외처리를 거쳐서 해당 Group객체에 데이터값들을 삽입했다. 그리고 해당 객체를 addGroup이라는 메서드로 실어보낼 것이다.

위 스크린샷들을 참고해서 코드를 추가하도록 하자. 이제 정말 Database 에 데이터를 저장하는 것만 남았다.
오늘 상당히 많은 부분을 진행했는데, 스크롤의 압박을 참아가며 따라와준 고갱님들 진심으로 감사드린다. 
다음 연재분에서는 sqlite를 이용한 Database 저장부분을 진행한다. 

수고많으셨습니다.