Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

Stacking Fire

일기장 - Record Repeater 출시 본문

개발

일기장 - Record Repeater 출시

라우비 2018. 4. 21. 01:13

3월 중순 쯤부터 준비한 일기장 앱이 앱 스토어에 올라갔습니다. 겉으로 보기에는 단순해 보이지만 부족한 탓에 고생한 게 많았어요ㅜㅠ 배운 점, 느낀 점들을 정리해 보고자 합니다.

다운로드

언어/플랫폼

  • Swift 4.1
  • iOS 10.0+ / macOS 10.12+

특징

  • iOS / macOS 기기 간 데이터 동기화 (CloudKit): 로컬 캐싱(NSCoding)한 정보를 버전별로 변화한 데이터만 선별적으로 패치.
  • iOS에서의 Push Notification을 통한 백그라운드 패치 적용
  • iPhone / iPad를 동시에 지원하는 Universal 앱. (UISplitViewController)
  • 사용자 컨텍스트에 따른 비동기 공유 작업 수행 (CKOperation)
  • UITextView 내에서 동적으로 서체 수정.
  • Cocoa, Cocoa Touch, CloudKit
  • SnapKit, SwiftLint

1. Core 코드 공유

iOS와 macOS 모두 CloudKit으로부터 정보를 받아 저장하고 변경사항별로 노티피케이션을 받아 패치하는 공통된 작업이 필요했습니다. 그래서 공통된 영역은 완전히 공유해서 쓰고, 각기 UI프레임워크에 맞게 보여주는 작업만 타겟을 나누어서 진행했습니다.


1-1. CloudKit

iOS와 macOS 간의 유틸리티 앱에 사용하기에는 최적의 솔루션인 것 같습니다. 별도의 백엔드 구성을 할 필요도, 비용을 낼 필요도 없으니까요. 사용자는 각자 자신의 iCloud 계정을 이용하니, (저에게) 정보가 노출될 위험도 없습니다. 다만 iOS와 macOS의 사용패턴이 워낙 천차만별이다 보니, 각 시나리오에 맞도록 최초 설정을 유도하는 것이 어려웠습니다. 아직도 커버하지 못한 시나리오가 있으리라 (특히 macOS에요.) 확신합니다. 계속 고쳐 나가야겠죠.


1-2. NS vs. UI

UITextView에서 하던 걸 NSTextView에서, UIViewController에서 하던 걸 NSViewController에서 하게 만드는 일의 연속이었습니다. 다른 듯 비슷한 두 프레임워크를 보면서 역사책을 보는 것 같아 흥미로웠습니다.

2. 유니버설 iOS 앱

iOS 버전은 처음으로 만들어 본 유니버설 앱입니다. UISplitViewController를 이용했고, 최대한 분기처리하지 않고 하나의 시나리오로 만들었습니다.


2-1. iPad 화면분할 모드

가장 신기했던 건, iPad Pro에서 화면분할 모드로 들어갈 때 짧게나마 앱이 비활성화(resign active)한다는 점입니다. 만약에 가장 좁은 Width에서 가장 넓은 Width로 사이즈 조정을 한다면, 3번이나 UIApplicationWillResignActive 노티피케이션을 부릅니다. 그 타이밍에 수행하던 작업이 생각지 못하게 3회 겹쳐서 수정해 주어야 했습니다. 관련정보


2-2. Detail 화면의 firstResponder

기본 Master-Detail View 템플릿을 관찰해보면, 매번 'Master'에서 항목이 선택될 때마다 'Detail'의 뷰 컨트롤러를 새로 초기화해서 가지고 옵니다. 서로 다른 뷰 컨트롤러가 불릴 수도 있으니 어찌보면 당연한데요. 이번 앱에서는 한 가지 종류의 디테일 뷰만 사용하기 때문에 매번 만들지 않고 쓰도록 설계했었습니다. 그런데 Detail 쪽의 UITextView에게 resignFirstResponder()가 작동하지 않는 문제가 생겼습니다.(정확히는 작동했다가, 다시 자동으로 편집 모드로 돌입합니다.) 아직 정확한 이유는 파악하지 못했지만, 다른 이유 때문에 기존의 방식으로 돌아가서 문제는 해결되었습니다.


2-3. 단축키 (KeyCommands)

처음으로 키보드 단축키를 만들어 보았습니다. 글 쓰는 기능이 있는 앱에서는 Cmd + N이나 Cmd + Return을 쓰는 게 워낙 익숙해져 있다 보니, 꼭 만들고 싶었거든요. 다만 스플릿된 뷰컨트롤러 중 어느 쪽이 firstResponder인지에 따라 사용할 수 있는 커맨드가 제한된다는 걸 알았습니다. 현재 응답하고 있는 쪽에 구현된 것만 사용할 수 있으니까요. 게다가 사용자가 기대하는 단축키 구성은 설계시의 기능 할당과는 다를 수 있다는 점을 알게 되었습니다.

3. macOS 앱

처음으로 만든 macOS용 앱이었는데요. 오히려 iOS에서 의문이었던 것들이 많이 해결되는 느낌이었습니다. 예를 들어서 iOS에서는 AppDelegate에 'keyWindow'라는 개념이 있는데요. 'key', 그러니까 핵심 윈도우라는 개념은 다른 여러 윈도우가 있거나 생길 가능성이 있어야 성립하죠. 근데 아시다시피 iOS에서 하나의 앱이 여러 윈도우를 가지는 일이 없으니, 혼란스러웠습니다. 그런 의문들이 macOS개발을 하면서 자연스럽게 풀렸습니다. 두 플랫폼을 함께 공부하면 시너지 효과가 있을 거 같아요. 아래는 mac 자체에 대해 배운 것들입니다.


3-1. NSMenuItem

메뉴바가 어떻게 만들어지는지, 왜 firstResponder가 중요한지 알게 되는 계기가 되었습니다. iOS에서 셀렉터 이름을 스트링으로 처리하는 게 이해가 안 됐었는데, 이 구조를 보다 보니 왜 그런지 알게 되었습니다. 메뉴 아이템에는 일단 다 메뉴를 만들어 놓고, 지금의 firstResponder가 그 이름의 메서드를 구현하고 있으면 활성화, 아니면 비활성화 시키더라구요. macOS에서는 메서드 이름이 명확해야 할 뿐 아니라 프로젝트 전체 맥락에서 무슨 뜻을 지니는지까지 고민해야 할 거 같습니다.


3-2. AutoLayout

기존의 iOS의 오토 레이아웃과는 비교도 안 되는 경우의 수를 고려해야 했습니다. 화면 사이즈를 자유 자재로 조정하니 당연한 일입니다. 우선순위(Priority)에 대해 다시금 공부하는 계기가 됐습니다.


3-3. View based NSTableView

생각해보니 macOS의 테이블에서는 iOS 테이블에 있는 섹션 헤더를 본 일이 별로 없는 거 같습니다. (열심히 찾아봤는데, 주소록 앱에 있었어요.) NSTableView에서는 섹션헤더 대신 groupRow라는 개념을 쓰는데요. 섹션헤더도 같은 셀인데 그룹로우로 지정해서 모양을 다르게 보이게 하는 식이었습니다. 구현 자체는 어렵지 않았지만, 문제는 데이터의 형태가 다르다는 점이었습니다. UITableView의 특성에 맞춰 섹션의 어레이 안에 각 로우의 데이터를 담아 놨기에, 수정이 불가피했습니다. 결국은 별도의 ViewModel을 만들어 처리해주도록 했습니다.

마치며

이런 종류의 유틸리티 앱을 만드는 것은 개발을 배우기 전부터 가지고 있었던 꿈입니다. 비록 처음에 생각했던 것 만큼 많은 기능을 넣지는 못했지만 기본적인 기능에 한해서는 최대한 타협하지 않고 만들려고 노력했는데, 그래도 고칠 게 계속 나오네요. 그래도 처음 온전히 제가 만든 걸 올리고 나니까 감흥이 새롭습니다. 

'개발' 카테고리의 다른 글

2017년 회고  (0) 2018.01.20
Comments