Balsamiq Mockups 사용해보다

꽤 전에 설치를 해두긴 했는데 계속 공부만 하느라 따로 사용할 시간이 없었습니다. 이제부터는 좀 사용해볼까 하고 있는데요. 제목처럼 Balsamiq Mockups(이하 Balsamiq)란 application 입니다. 예전에 보면 화면 디자인이나 구성하기 편하게 아이폰 모양의 메모지가 판매되기도 했었던 걸로 기억합니다. Balsamiq은 UI design을 하기 위한 tool로 별도로 아이폰에 필요한 항목도 마련해 두고 있습니다. 아이폰 모양의 메모지 같은게 필요 없는거죠. 사실 가볍게 사용하기엔 메모지가 더 좋긴 하겠습니다만, 더 마음에 드는 이유는 제공되는 이미지들이 모두 손으로 직접 그린 듯한 느낌의 이미지들이기 때문입니다. 저처럼 그림은 좋아하지만 소질이 없는 사람들에게 딱 적합한 tool이 아닐까 싶네요. :) 아무거나 이것저것 드래그해서 막 나열해본 화면은 아래와 같습니다.


그림 괜찮은가요? 이렇게 구성하는데 1분 정도 걸린 것 같습니다. 디테일한 부분들도 수정은 가능하지만 거의 건들지 않고 그냥 드래그만 했을 때의 상태랍니다. 아이폰 이외에도 일반적으로 UI 구성할 때 필요한 것들은 거의 다 템플릿으로 제공되고 있습니다. 그리고 나서 파일로 저장할 때 PNG, PDF 등으로 저장이 가능한데 근데 전 아직 데모버전을 사용하고 있어서 저장이 불가능한 상태에요. :(


정말 괜찮고 멋진 UI 디자인을 해보고 싶으시다면 아래의 공식 사이트에서 다운로드 하셔서 한 번 사용해보시면 되겠습니다.

http://www.balsamiq.com/

라이센스 비용은 $79 네요. 그냥 구매해버리고 싶은 생각도 듭니다. :)

이해를 돕기 위한 Objective-C 문법 (Ch.9)

Chapter 9가 마지막입니다. 몇 주 전부터 느끼던 건데, 제가 보고 있었던 Head First iPhone Development 라는 책이 초심자들이 무작정 따라하면서 흥미를 느끼기에는 괜찮긴 한데 Head First 시리즈가 가지고 있는 특성 (여기저기 낙서하듯이 흐트러져 있는) 때문에 종종 복잡하고 혼란스럽게 느껴질 때가 있었습니다. 또 진도가 나갈수록 새로운 control의 사용법들이 등장했는데, 이런 내용은 어차피 나중에도 참조해야 하는 거라서 chapter 7 쯤 되니까 직접 부딪히면서 배우는게 낫겠다는 생각이 들더군요. 어쨌든 마지막 chapter에서는 고급과정인 카메라와 맵킷을 사용하는 방법이 등장합니다. 시뮬레이터 기반으로 구현했기 때문에 실제로 카메라를 직접 동작시킬 수는 없었지만 Map Kit과 Core Location의 활용은 꽤 흥미로웠습니다.


Flipping

여러 application을 사용해보다 보면 화면전환시의 animation 중에 화면이 뒤집히면서 변경될 때가 있습니다. 이게 flipping 입니다. 이것을 구현하는 방법은 매우 간단합니다. 전환하는 스타일을 flip 하겠다는걸 의미하는 UIModalTransitionStyleFlipHorizontal 상수만 사용하면 되더군요. 물론 몇가지 작업도 해야하지만 보통의 view를 사용할 때와 같습니다.

위의 사용예문을 보면, 우선 CapturedPhotoViewController.xib 파일로 CapturedPhotoViewController의 객체를 생성했습니다. 그리고 생성한 controller의 modalTransitionStyle을 UIModalTransitionStyleFlipHorizontal로 지정해주고 controller를 modal view로 설정해주는 걸로 끝이네요. 간단합니다. 정말. 참 showInfoButtonPressed 는 화면 전환을 명령할 수 있는 button 등을 미리 만들어두고 IBOutlet으로 만들어서 연결되어 있어야 호출이 가능하겠죠.


UIImagePickerController

카메라를 사용하기 위해서는 UIImagePickerController를 이용하면 된다고 합니다. UIImagePickerController를 사용하게 되면 일반 사용자들은 카메라로 사진을 찍거나 라이브러리에서 사진을 선택해서 가져올 수 있게 됩니다. Controller를 생성한 후에 sourceType이라는 속성에 어떤 값을 지정하는냐에 따라 기능을 선택할 수 있는데, 속성값으로는 UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera, UIImagePickerControllerSourceTypeSavedPhotosAlbum 세가지가 있습니다. 각각은 photo library, camera, photo album에서 이미지를 가져오겠다는 것을 의미하며 복수 선택도 가능합니다. 일반적인 경우처럼 “|(OR)” 를 쓰면 되겠죠. 또 현재 application이 동작중인 device에서 어떤 것을 지원하고 있는지 알고 싶다면, isSourceTypeAvailable 이라는 method를 써서 분기하면 되겠습니다.


AR (Augmented Reality)

최근 유행하고 있는 증강현실을 구현해보고 싶다면 어떻게 해야 하는지 궁금했습니다. 뭔가 복잡할 것 같기도 했고, 구석구석 따져보면 간단할 것 같기도 했는데 카메라로 비치는 실사 자체가 호기심을 자극하기 때문에 그런 혼란을 갖게 되는지도 모르겠습니다. 책에서는 아주 짧게 언급되어 있는데 UIImagePickerController 위에 overlay view를 올리면 된다고 하네요. 이 부분은 관심이 많기 때문에 나중에 자세히 확인해보고 정리할 생각입니다.


이해를 돕기 위한 Objective-C 문법 (Ch.8)

Chapter 8에서도 계속 같은 내용의 application을 개선하고 업데이트 하는 내용입니다. 주로 다루고 있는 내용은 data model에 변경사항이 생겼을 때 Core Data를 이용해서 쉽고 빠르게 처리할 수 있는 방법이구요. 수배자 명단에서 수배자를 검거했다고 선택하게 되면 검거자 리스트에도 해당 data가 표시되는 것까지 처리하고 있네요. 이번 chapter까지 끝내면 심심하지만 원래 의도했던 기본 기능은 갖출 수 있습니다.


Data Model의 변경

기존의 data model을 사용하다가 속성을 추가, 삭제, 변경하고 싶은 경우가 분명히 발생할 것 같습니다. 보통의 경우라면 DB 자체를 다루게 될테니 DB 스키마가 변경됨을 의미하고, 귀찮고 복잡한 작업을 하나하나 해줘야 합니다. 하지만 Data Core를 이용하면 작업이 훨씬 줄어들 수 있습니다. 잘 생각해보면 처음에 Data Core를 사용하기 시작할 때 부터 DB와 관련된 복잡한 작업은 하지 않았었는데, 확실히 이 부분은 편리하다는 생각이 드네요. 아무튼 Data Model을 변경할 일이 생기면 아래의 작업들을 순서대로 해주면 됩니다.

1. 변경할 기존의 data model 선택

2. Design > Data Model > Add Model Version 메뉴 선택

3. 2.과정을 거쳐서 생성된 새로운 버전의 data model 선택

4. Design > Data Model > Set Current Version 메뉴 선택

5. Data Model 변경


Managed Object Context에 data 저장 그리고 취소

data를 저장하기 위해서는 save (commit 한다는 것을 의미), 되돌리고 싶다면 rollback message를 보내라고 되어있습니다. 참 직관적이라는 생각이 드네요. save, rollback, …:)


viewWillAppear / viewDidLoad

지금까지 참 많이 보게 되었던 method 들입니다. 이외에도 몇가지가 더 있지요. View를 표시하는 method들 여러개를 한꺼번에 정리할 필요가 있어 보입니다. 일단 viewWillAppear와 viewDidLoad를 보면 method 이름이 다른 것처럼 의미와 용도에도 명확한 차이가 있습니다. viewWillAppear는 해당 view가 화면에 표시될 때 마다 매번 호출되는 method 입니다. 예를 들어 navigation control을 사용한 application에서 item 한가지를 선택해서 상세 view가 표시되는 경우 viewWillAppear가 호출되고, 원래 view로 되돌아가서 다시 상세 view가 표시되면 다시 호출이 됩니다. 그러므로 매번 호출될 필요가 있는 구문들만 viewWillAppear에 넣어주어야 할 것 같습니다. 반면에 viewDidLoad는 전체 view (xib file)가 메모리에 올라올 때 한 번만 호출되는 method 입니다. 정확히는 load된 직후에 호출되겠네요. 이름에 did가 있으니까요.


이해를 돕기 위한 Objective-C 문법 (Ch.7)

오랜만에 정리합니다. 계속 미루고 있다가 책을 마지막까지 다 보고 나서야 정리할 생각을 하게 되었습니다. 했던거 마무리는 해야 하니까요. 이번 chapter 7에서는 새로운 application을 만드는 것으로 시작을 합니다. 수배자에 대한 정보를 listing 해주는 application 인데, chapter 9 까지 이어지네요. chapter 7에서는 tab bar를 사용해서 수배자와 검거된 사람들의 list를 분리하고 그에 필요한 data 관리는 Core Data로 하는 방법을 알려주고 있습니다. Core Data는 다시 별도로 정리를 해야할 것 같습니다. 꽤 복잡해 보여서요. 물론 직접 DB 관리하면서 쿼리문을 코드에 넣는 것보다는 훨씬 낫겠지만요.


Tab bar icon 추가 혹은 변경

Tab bar에 있는 물음표를 선택하던가 직접 구성요소를 다 펼쳐서 Tab bar item을 선택합니다. 그 이후에 오른쪽의 속성 창에서 Identifier 부분을 Custom으로 변경하고 Image에 넣고자 하는 혹은 바꾸고자 하는 image 파일을 선택해주면 됩니다.

위의 그림처럼 설정하면 끝. 간단합니다. :)


Core Data에서 Entity의 attributes 옵션들

Entity를 새로 구성하려고 attribute 들을 추가하고 수정하다보면 몇 개의 옵션들이 있는 것을 볼 수 있습니다. 그 중에서 Transient는 data를 따로 저장할 필요가 없는 임시 attribute 라는 걸 알려주는 용도이며, Indexed는 Core Data가 index 값을 별도로 만들어 빠른 검색을 가능하게 만들 필요가 있을 때 사용합니다.


Core Data의 세가지 요소

Core Data는 세가지 요소로 구성된다고 책에 언급되어 있습니다. 개인적으로는 entity도 하나의 요소가 되는거 아닌가 싶은데 일단 책에서는 그렇게 말하고 있네요. 세가지는 아래와 같습니다.

Managed Object Context : Data를 관리하는 녀석. Entity로 만들어낸 data model 들도 context가 관리합니다.

Persistent Store Coordinator : 아래 store를 관리하는 역할을 수행합니다.

Persistent Object Store : 용어 그대로 store 입니다. 책의 예제에서는 sqlite 파일이 되겠습니다.


NSFetchRequest

Managed Object Context에게 찾고자 하는 객체를 알려주기 위한 용도로 NSFetchRequest 라는 클래스를 사용해야 합니다. NSFetchRequest를 사용할 때 크게 세가지를 결정해줘야 하는데, Entity Info, Predicate, Sort Descriptor 가 그 것입니다. 어떤 entity를 찾을건지 결정해주고(Entity Info), 충족해야 하는 조건 혹은 검색 조건을 만들어줘야 하구요(Predicate). 조건을 충족하는 data가 있을 경우에 정렬시켜서 뽑을 수 있습니다.(Sort Descriptor)


NSSearchPathForDirectoriesInDomains

책에서 계속 simulator를 사용하고 있기 때문에 실제 device와 약간 차이가 나는 부분들이 있습니다. 그 중에 하나가 DB가 존재하는 위치인데, device와 달리 simulator 사용시에는 다른 디렉토리에 저장이 되기 때문에 별도의 method를 사용해서 DB file을 찾아줘야만 합니다. 그 때 사용하는 method가 NSSearchPathForDirectoriesInDomains 입니다. 이 method의 prototype을 살펴보니 지금까지 보아왔던 Objective C의 method와는 많이 다르네요. C, C++, Java 등에서 흔히 사용하는 method와 같은 모습입니다. (아래의 그림, NSSearchPathForDirectoriesInDomains prototype)

NSSearchPathForDirectoriesInDomains method의 문서를 살펴보니 특정 directory, domain을 위한 경로 문자열을 리스트로 넘겨준다고 되어있습니다. NSSearchPathDirectory와 NSSearchPathDomainMask는 각각 enum으로 여러가지 상수들을 포함하고 있습니다. Chapter 7의 예제에서는 각각 NSDocumentDirectory, NSUserDomainMask를 사용했구요.


NSManagedObject의 생성

예제에서는 NSManagedObject를 context에서 가져오는 것으로 설명되어 있습니다만, 별도로 생성하는 방법도 있다고 합니다. 일반적인 클래스 객체의 생성처럼 alloc, init만 해서 생성하는 것은 안되고 아래처럼 entity에 대한 정보도 필요하다고 되어있네요.

[NSEntityDescription insertNewObjectForEntityForName:@"Fugitive"

inManagedObjectContext:managedObjectContext];