Jekyll2020-03-21T06:55:55+00:00https://mijeongjeon.github.io/feed.xml未定의 언젠가는 개발 블로그아무것도 하지 않는 iOS 모바일 개발자의 기술 블로그입니다.이게 다 패키지 때문이야, virtualenv2018-08-10T14:02:00+00:002018-08-10T14:02:00+00:00https://mijeongjeon.github.io/jekyll/update/2018/08/10/virtualenv<h2 id="이게-다-패키지-때문이야-virtualenv">이게 다 패키지 때문이야, virtualenv</h2>
<p><img src="/assets/imgs/180810/image1.png" alt="" /> <br />
<br /></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">virtualenv</code>와의 만남 이전에 파이썬(Python)이 있었는데, 프알못인 내가 ‘파이썬’을 들었을 때 처음 떠오르는건 경주월드의 ‘파에톤(Phaethon)’이었다🎢(부아앙)….<br />
쉽게 말해 파이썬도 파이썬 패키지도 전혀 알지 못하는 상태라 왜 <code class="language-plaintext highlighter-rouge">virtualenv</code>를 사용해야 하는지 이해되지 않았고, 프로젝트를 만들 때 마다 궁금해하다 결국 이렇게 문서를 정리하게 되었다(는 fake, 일하기 싫어서 😂).
<br />
<br /></p>
</blockquote>
<h4 id="virtualenv-필요성">Virtualenv 필요성</h4>
<p><a href="https://virtualenv.pypa.io/en/stable/">Virtualenv 공식 사이트</a>에 의하면 <strong>“virtualenv is a tool to create isolated Python environments.”</strong></p>
<p>번역하면 독립된 파이썬 환경을 만들기 위한 툴인데, 왜 파이썬을 독립시켜야 하는거지?라는 의문이 생기지 않을 수 없다. 열심히 서치해본 결과 이유는 바로…(쓸데없는 농담은 하지 말아야지) <strong>파이썬의 무한한 기능</strong> 때문이라 할 수 있다.</p>
<p>파이썬 언어로 개발된 무수히 많은 패키지를 이용해 다양한 기능을 구현할 수 있어 파이썬은 많은 개발자가 프로젝트에 널리 사용하고 있다. 그리고 일반적으로 하나의 프로젝트에 사용되는 패키지의 개수는 손가락으로 세기 무색할 만큼 많은 편이다. 그런데 다양한 패키지를 사용하다 보면 이런저런 문제가 발생하게 되는데 다음과 같은 경우를 생각해보자.</p>
<p><strong>경우 1</strong> 두 개의 프로젝트를 관리하는데 두 프로젝트 모두 <code class="language-plaintext highlighter-rouge">iFoo</code>라는 패키지를 사용한다. A 프로젝트에서는 버전 1.0.0의 <code class="language-plaintext highlighter-rouge">iFoo</code>를 사용하는데, B 프로젝트에서는 <code class="language-plaintext highlighter-rouge">iFoo</code> 버전 2.0.0 기능이 필요하다면??</p>
<p><strong>경우 2</strong> 이미 설치된 응용프로그램을 업데이트하지 않고 그대로 유지하고 싶은데, 관련 라이브러리의 버전이 변경되버려 응용프로그램이 작동하지 않는 경우에는 어떻게 대응해야 하지?</p>
<p><strong>경우 3</strong> 여러 사람들과 공유하는 프로젝트의 글로벌 디렉토리에 패키지를 설치하면 안 되는 상황엔 어떻게 프로젝트를 관리해야 할까?</p>
<p>등등…</p>
<p>위와 같은 상황뿐만 아니라, 다수의 패키지를 사용하다 보면 패키지 버전이나 의존성(dependency) 때문에 충돌이 일어나는 경우가 비일비재하다.</p>
<p>이러한 모든 경우를 해결하기 위해 패키지를 독립적으로 관리하는 방법이 등장했는데 Python에서 사용되는 기능이 바로 <code class="language-plaintext highlighter-rouge">virtualenv</code>(가상환경을 의미하는 Virtual Environment의 줄임말)이다.</p>
<p>정리하자면, <code class="language-plaintext highlighter-rouge">virtualenv</code>를 사용하면 독립된 개발환경을 구축 할 수 있고, 다른 환경과 패키지를 공유하지 않기 때문에 각 프로젝트에 필요한 버전의 패키지를 자유롭게 사용할 수 있다.</p>
<p><br /></p>
<h4 id="virtualenv-사용법">Virtualenv 사용법</h4>
<dl>
<dt><strong>1. 시스템에 <code class="language-plaintext highlighter-rouge">virtualenv</code>를 설치한다.</strong></dt>
<dd><code class="language-plaintext highlighter-rouge">virtualenv</code>는 가상환경을 구축하기 위한 패키지이므로 가상환경이 아닌 시스템 디렉토리에 설치해야 하며 처음 1번만 설치하면 어디서나 활용할 수 있다.</dd>
</dl>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pip install virtualenv
</code></pre></div></div>
<dl>
<dt><strong>2. <code class="language-plaintext highlighter-rouge">virtualenv</code>를 사용한다.</strong></dt>
<dd>가상환경을 구축하고 싶은 디렉토리에서 가상환경 생성을 의미하는 명령어인 <code class="language-plaintext highlighter-rouge">venv</code>을 실행한다.</dd>
</dl>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>virtualenv venv
</code></pre></div></div>
<p><strong>3. 필요한 패키지를 설치한다.</strong></p>
<p><em>자세한 내용은 공식 사이트의 <a href="https://virtualenv.pypa.io/en/stable/userguide/">User Guide</a> 문서 참조 📄</em></p>
<h4 id="참고">참고</h4>
<ul>
<li>파이썬 버전 2에는 위처럼 별도로 <code class="language-plaintext highlighter-rouge">virtualenv</code> 패키시를 설치해야 사용할 수 있지만, 워낙 많이 사용되는 패키지이다 보니 파이썬 버전3에는 기본 모듈로 포함되어 별도의 설치 없이 바로 사용할 수 있다.</li>
<li>용량이 큰 패키지의 경우 모든 환경마다 따로 설치하면 시간과 메모리가 많이 소모되니 일반적으로 사용하는 패키지의 경우 글로벌로 설치하는 것을 고려하는 것이 좋다.</li>
</ul>이게 다 패키지 때문이야, virtualenv내겐 너무 목성 같은, Jupyter Notebook2018-08-08T13:52:09+00:002018-08-08T13:52:09+00:00https://mijeongjeon.github.io/jekyll/update/2018/08/08/jupyter_notebook<h2 id="내겐-너무-목성-같은-jupyter-notebook">내겐 너무 목성 같은, Jupyter Notebook</h2>
<p><img src="/assets/imgs/180808/image1.png" alt="" /> <br />
<br /></p>
<blockquote>
<p>친근한 두 개의 단어, 주피터(목성-은 jupiter이지만-)와 노트북(notebook-공책)의 결합인 Jupyter notebook. 머신러닝을 할 때 매번 터미널에 입력하는 <em>jupyter notebook</em>라는 녀석을 매번 따라 적기만 하다가 문득 궁금해져서 이것저것 찾아보다 정리하게되었다(라는 fake, 일하기 싫어서 딴짓 중입니다 ;).
<br />
<br /></p>
</blockquote>
<h4 id="1-notebook-document노트북-문서-1">1. Notebook document(노트북 문서) [<a href="http://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/What%20is%20the%20Jupyter%20Notebook.html#Introduction">1</a>]</h4>
<p>Notebook document(혹은 notebooks)은 Jupyter Notebook 애플리케이션을 통해 생성된 문서를 말한다.<br />
Julia, Python, R 등의 컴퓨터 코드뿐만 아니라 문자, 방정식, 표 등과 같은 다양한 형태로 작성할 수 있는 문서이다. 이러한 특성 때문에 표, 설명, 방정식, 미디어를 결합한 단일 문서에 코드의 결과를 함께 출력할 수 있으며, *.ipynb와 같은 포맷을 지니는 노트북 문서를 파일 형식으로 타인과 공유할 수있다.
<br /></p>
<h4 id="2-jupyter-notebook주피터-노트북">2. Jupyter Notebook(주피터 노트북)</h4>
<p>Jupyter Notebook은 Notebook document를 작성하거나 실행할 수 있는 웹 기반의 대화형 애플리케이션이다.<br />
Jupyter라는 오픈 소스 소프트웨어 프로젝트의 메인 애플리이션인 Jupyter Notebook 직관적인 사용법, 재현 가능성 그리고 신속한 개발이 가능해 다양한 분야에서 활용되고 있다. 전 세계적으로 학계, 정부, 기업에서 상업용 및 비영리 서비스 구축을 위해 널리 사용되고 있다고 한다.<br />
Jupyter Notebook 애플리케이션은 인터넷이 연결되어있지 않은 상태에서 로컬로 실행할 수 있으며, 서버에 Jupyter Notebook을 설치해두고 네트워크를 통해 접근할 수도 있다.<br />
<br /></p>
<h4 id="3-jupyter의-어원은">3. “Jupyter”의 어원은?</h4>
<blockquote>
<p>(개인적으로 가장 궁금했던 부분) 프로젝트 이름가 Jupyter인 이유에는 아래와 같이 세 가지 이유가 있다고 한다. [<a href="https://github.com/jupyter/design/wiki/Jupyter-Logo">2</a>]</p>
</blockquote>
<p><strong>첫 번째</strong> 스펠이 유사한 목성(jupiter)에서 시작되었다고 한다. 설명에 따르면 과학의 전통과 이념을 불러일으키는 이름으로 프로젝트명을 짓고 싶은 의지를 담았다고 한다.</p>
<p><strong>두 번째</strong> Jupyter가 지원하는 핵심 언어는 Julia, Python 그리고 R인데, 세 가지 언어의 앞글자를 연결하면 절묘하게 jupyter와 비슷해지는 것을 알 수 있다. 특히 Python의 ‘y’를 존중하기 위해 목성의 스펠인 ‘jupiter’의 ‘i’를 ‘y’로 치환(!!)했다고 한다.</p>
<p><strong>세 번째</strong> 목성의 위성을 최초로 발견했던 갈릴레오가 자신이 연구한 내용을 정리해 출간물이 냈었는데, 그 책자가 근거 데이터가 잘 수록되어있는 자료의 시초였다고 한다. 이러한 데이터는 과학적 재현성에 매우 중요한 의미를 지니는데 Jupyter 역시 재현성에 큰 초점을 맞추고 있기 때문에 jupyter라는 단어를 사용했다고도 한다.
<br /></p>
<h3 id="4-마무리">4. 마무리</h3>
<p>jupyter notebook을 글로 정리해도 실제로 잘 사용하지는 못하겠지만 그래도 포스팅을 남기니까 일한 것 같은 느낌적인 느낌이 들어서 좋구나~ 근데 Jupyter 어원을 혹시 나만 궁금해 했던건 아니겠지? 🤭</p>내겐 너무 목성 같은, Jupyter NotebookBlink - Quick Memo 개발 과정2018-04-05T09:52:09+00:002018-04-05T09:52:09+00:00https://mijeongjeon.github.io/jekyll/update/2018/04/05/Blink_app_story<h2 id="심플한-메모-앱-blink-이야기">심플한 메모 앱, Blink 이야기</h2>
<p><img src="/assets/imgs/180405/iTunesArtwork.png" alt="" /> <br />
“당신은 메모를 잘 하는 사람입니까?”<br />
“아주 가끔은….?”
<br />
<br /></p>
<p>그리 머지않은 과거, 우리 손에 작은 수첩과 펜이 들려있던 시절이 있었다. 하지만 지금은 스마트폰이 그 자리를 차지했고 수첩을 사용하는 사람은 쉽게 찾아 볼 수 없는데, 스마트폰의 세련된 모습뿐만 아니라 오랜 기간 수첩이 수행했던 단순한 기능과 비교할 수 없이 다양하고 똑똑한 기능으로 사람들의 마음을 순식간에 빼앗아갔기 때문일테다.<br />
그런데 오히려 굉장한 기능과 복잡함 때문에 가끔은 정작 필요한 기능을 제대로 사용하지 못할 때가 종종 있는데 내게는 유난히 Todo 앱이 그러했다. 옛날처럼 흰 종이 한 장과 펜만 있으면 되는데 달력/서버와의 연동, 기간 설정, 카테고리 입력, 태그 달기, 수많은 입력 사항 등등 내가 사용하지 않을 멋진 기능들이 오히려 나를 메모에서 멀어지게 했다. 덕분에 스마트폰을 손에 쥔지 5년이 지났지만 그 어떤 Todo/Memo 앱에도 정착하지 못하고 포스트잇과 기본 메모 앱 사이를 왔다 갔다 할 수밖에 없었다.</p>
<p>그러던 어느 날, John을 만나 심플한 메모 앱, Blink 기획 이야기를 들었다. 획기적이었다! 지금까지의 Todo/Memo 앱은 한 줄에 하나의 아이템이 들어가는 즉, 리스트 형식이었는데 Blink는 수첩에 간단하게 메모하던 방식대로 한줄에 여러 아이템을 착착 적어나가는 방식이었다. 한 장의 흰 종이 그리고 펜. 그 이상도 이하도 아닌 정말 메모를 위한 메모 앱이었다.</p>
<p>정말 사용하기 편한 앱이겠어! 내가 원하던 앱이군!! 이제 남은 문제는 단 하나. 프알못인 내가 어떻게 이걸 구현하지?? 😳<br />
<br /></p>
<h2 id="진짜-개발-이야기">진짜 개발 이야기</h2>
<h3 id="0-개발-환경">0. 개발 환경</h3>
<ul>
<li>Platform : iOS</li>
<li>IDE : Xcode</li>
<li>Language : Swift</li>
<li>DataBase : Realm</li>
<li>Crash Report : Fabric</li>
<li>Version Control : Github</li>
<li>without Storyboard(왜 그랬는지 그 당시 나는 스토리보드를 멀리했다. 그렇다고 Autolayout을 사용하지 않은 건 아니다.)
<br /><br /></li>
</ul>
<h3 id="1-엔진-개발">1. 엔진 개발</h3>
<h4 id="핵심기능">핵심기능</h4>
<ul>
<li>가로 방향 아이템 배열</li>
<li>단일 아이템 다중 분산</li>
</ul>
<h4 id="class">Class</h4>
<ul>
<li>UICollectionViewController</li>
<li>UICollectionViewControllerFlowLayout</li>
</ul>
<p><br /></p>
<p>아직도 생생한 1년 전 봄, Blink iOS 개발이 시작됐다.<br />
Blink는 메인화면과 셋팅화면 2가지 화면으로 구성된 단순한 구조의 앱으로 디자인도 플레인하며, 소요되는 색상이나 이미지도 많이 없는 편이라 혼자서 구현하기에 그리 어렵진 않을거라 생각했다.</p>
<p><img src="/assets/imgs/180405/blink_1.png" alt="" /></p>
<p><br /></p>
<p>작은 문제가 있다면 메인화면 레이아웃 구성. 우리는 이 레이아웃을 Blink의 ‘엔진’이라 불렀는데 역시 엔진은 엔진. 생각보다 만드는데 꽤 오랜 시간이 걸렸고, 해결해야 할 문제는 크게 3가지였다.
<br />
<br /></p>
<hr />
<p><code class="language-plaintext highlighter-rouge">(문제1) 세로로 아이템을 나열하던 방식을 가로 방향으로 변경하기</code></p>
<p>한 줄에 여러 개의 아이템을 넣고, 각 아이템을 독립적으로 관리(터치)할 수 있어야 했다.</p>
<p>가장 먼저 생각난 방법은 <strong>UILabel 쌓기</strong> <br />
UILabel를 박스라고 생각하고 각 UILabel 하나에 아이템 하나를 담은 후 공간을 박스로 채워가는 방법. 그리고 각 UILabel에 TapGesture를 붙여서 아이템이 탭 될 때마다 어느 아이템이 선택된건지 체크하면 되겠지? 라고 생각했다. 그런데 이렇게 하려니 새로운 메모가 추가 될때마다 각기 다른 너비의 UILabel을 모두 계산한 뒤 그에 맞게 모든 UILabel의 frame을 매번 업데이트하고, 수백 개의 UILabel의 제스처를 관리하려니 생각만 해도 로드가 너무 컸다. UILabel을 UIButton으로 변경해도 상황은 마찬가지(지금 생각해도 🍵). 고민에 고민을 거쳐 생각해낸 방법은</p>
<p><code class="language-plaintext highlighter-rouge">(해답1) UICollectionViewController</code></p>
<p>그 쯔음 Custom Photo Album을 구현하느라 한참 빠져있었던 클래스였다. 그래, 내가 모든 Label의 프레임을 일일이 계산해서 뿌려주는 건 너무 힘들지만 친절한 UICollectionViewController의 힘을 빌리면 아이템 추가도, 정렬도, 관리도 훨씬 손쉽게 할 수 있을거야.<br />
그렇게 나는 컬렉션 뷰와 친해졌다.
<br />
<br /></p>
<hr />
<p><code class="language-plaintext highlighter-rouge">(문제2) 아이템이 길면 넘치는 부분을 다음 줄로 넘겨주기</code></p>
<p>화면의 가로길이를 넘는 아이템을 어떻게 잘 잘라서 다음 줄로 넘겨줄 것인가? <br />
여기서부터 길고 긴 고민과 고난의 시간이 시작되었다.<br />
길고<br />
기<br />
ㄹ<br />
긴<br />
여정<br />
사용자가 입력하는 아이템의 길이가 짧으면 오케이지만, 화면 가로길이보다 긴 아이템을 입력하거나, 아이템을 착착 쌓아가다가 화면 오른쪽 엣지를 넘어가면 그땐 어떻게 하지?? <br />
예를 들면 아래와 같은 상황이다.</p>
<p><img src="/assets/imgs/180405/blink_3.png" alt="" /></p>
<p><br /></p>
<p>새로운 아이템인 ‘가을이 간식’을 입력하면 오른쪽 끝에 있던 단어 ‘프란츠 카프카 책 사기’는 ‘프란츠 카프, 카 책 사기’로 쪼개지면서 자연스럽게 다음 줄로 넘어가야 했다.</p>
<p>사용자가 아이템을 추가, 수정 그리고 삭제 할 때마다 화면 레이아웃이 유격 없이 위와 같이 업데이트돼야 했다. 이를 위해 하나의 아이템을 화면 길이에 맞게 둘(혹은 셋, 넷..)로 쪼개주는 기능이 iOS에 있을까 해서 혹시나 하고 찾아봤지만 역시나 없었다. 유사한 레이아웃을 가진 앱도 보이지않고, Stack Overflow를 찾아봐도 비슷한 경우도 없었다😥. 처음에는 사용자가 입력하는 아이템 자체를 화면 길이와 비교해 자르고 붙이려 했지만 이 방법은 DB를 대책 없는 혼란에 빠지게 했다. 아이템 하나가 추가되거나 변경될 때마다 DB의 모든 데이터를 쪼개고 붙이고 삭제하고 할 수는 없는 노릇이었다. 정말 상상만 해도 끔찍한 처리방식이다. 하지만 프알못인 나는 일단 시도해봤다. 결과는 아래와 같았다.</p>
<p><br /></p>
<blockquote>
<p>시도 1.<br />
<img src="/assets/imgs/180405/blink_2.png" alt="" />
<br /></p>
</blockquote>
<p>화면에 난감한 장면이 펼쳐졌다. 분명 내가 입력한 아이템은 4개였는데 DB에 같은 게 복사되고 또 복사 되고 또 복사되고…뫼비우스의 띠? 헤헷 =ㅅ=</p>
<p>이런 방법으로는 결코 안정적인 메모앱을 만들 수도 없었고, 데이터 관리도 엉망이 될 게 분명했다. 다른 방법을 찾아야했다. (아무리 생각해도 사용자가 입력한 데이터 원본은 절대 건드리면 안 되는 거였다. 왜 당연한 걸 몰랐을까?)</p>
<p><code class="language-plaintext highlighter-rouge">(해답2) 사용자가 입력하는 데이터 원본은 그대로 유지하되, 화면에 뿌려주는 아이템은 따로 관리</code></p>
<p>DB에 입력되는 사용자의 데이터는 건드리지 않고, 메모리에서만 존재하는 새로운 데이터 체계를 만들었고, 화면 길이와 아이템의 가로 길이를 비교해 자르거나 붙이는 작업을 계속해줬다.</p>
<p>그 결과 아래와 같은 화면으로 한 발짝 더 나아갈 수 있었다.</p>
<p><br /></p>
<blockquote>
<p>시도 2.<br />
<img src="/assets/imgs/180405/blink_4.png" alt="" />
<br /></p>
</blockquote>
<p>입력한 DB가 잘 유지되고 있음을 확인하고 디자인을 입혔다.</p>
<p>아직 레이아웃은 엉망이지만…</p>
<p>아이템 간의 간격을 일정하게 맞추고, 적절한 지점에서 아이템을 잘라주는 게 쉽지 않았다.
<br />
<br /></p>
<hr />
<p><code class="language-plaintext highlighter-rouge">(문제3) 아이템의 너비를 어떻게 정확하게 계산할 것인가</code></p>
<p>계획했던 레이아웃에 가까이 오긴 했지만, 아이템이 깔끔하게 정렬되지지 않는 게 문제였다. 게다가 위 이미지에는 띄어쓰기가 없는데 아이템에 띄어쓰기라도 들어가면 대혼란이 빚어졌다.<br />
헤헷 =ㅅ= 초반에 아이템의 가로 길이를 측정하던 방식은 아이템의 글자 개수를 카운트한 뒤, 글자 하나가 지니는 대략적인 사이즈를 곱해주는 것이었다.
<br /></p>
<p>예) 아보카도 = 4(글자 개수) * 15(한 글자당 너비) = 60 point
<br /></p>
<p>당연히 위 방식으로는 정확한 너비를 구할 수 없었다. 특수문자나 띄어쓰기가 들어가면 대혼란이 오는 것도 당연했다. 그리고 한글 기준의 너비였으니 영어, 중국어, 일본어, 러시아어, 아랍어, 프랑스어 등등으로 입력하면 레이아웃이 한층 더 심각하게 깨어지는 건 굳이 테스트해보지 않아도 명백했다. 아이템의 정확한 가로길이를 계산해야만 했다.</p>
<p><code class="language-plaintext highlighter-rouge">(해답3) 아이템의 글자를 분리해 다음 각각의 정확한 너비 측정 후 합산</code></p>
<p>아이템이 추가/변경될 때마다 모든 아이템을 계산해야 했기 때문에 중복되는 과정 없이 연산을 단순하게 만드는 게 중요했다. 새로운 방식을 적용한 결과는 아래와 같았다.</p>
<p><br /></p>
<blockquote>
<p>시도 3.<br />
<img src="/assets/imgs/180405/blink_7.png" alt="" />
<br /></p>
</blockquote>
<p>띄어쓰기도, 특수문자도, 영어도 꽤 잘 계산해서 잘라준다!</p>
<p>헤헷 =ㅅ= 하지만 여전히 아이템 사이의 간격을 일정하게 만드는 문제가 남아있었다.</p>
<p>여기서부터는 UICollectionViewControllerFlowLayout 프로토콜의 여러가지 메서드를 조정하면서 맞춰갔다. 당시 나는 iOS의 UICollectionViewController가 얼마나 훌륭한 클래스인지 제대로 느낄 수 있었고 결국 지금과 같은 화면을 구현해낼 수 있었다.</p>
<p><br /></p>
<blockquote>
<p>결과<br />
<img src="/assets/imgs/180405/blink_5.png" alt="" />
<br /></p>
</blockquote>
<p>역시, 집에 갈 땐 메로나 :)
<br />
<br />
<br /></p>
<h3 id="2-업데이트">2. 업데이트</h3>
<p>Blink는 2017년 5월 17일 버전 1.0.0을 출시한 뒤 지금(2018년 4월 5일)까지 40번 가량의 업데이트를 거쳐 버전 1.4.4가 되었다.</p>
<p>그러는 동안 아래와 같은 다양한 기능이 추가되었다.
<br /></p>
<ul>
<li>스마트 제스처 : 위아래 드래그(UIPanGesture)를 이용한 아이템 아카이브/상단으로 보내기 기능<br />
<img src="/assets/imgs/180405/blink_9.png" alt="" /><br />
<br />
<br /></li>
<li>음성 입력 : 타자 입력이 힘들 때 사용하기 좋은 음성 입력 기능<br />
<img src="/assets/imgs/180405/blink_10.png" alt="" /><br />
<br />
<br /></li>
<li>반복 알림(한시간/하루) : 깜빡(Blink)하지 않게 중요한 건 반복 알림으로 알려주는 기능<br />
<img src="/assets/imgs/180405/blink_11.png" alt="" /><br />
<br />
<br /></li>
<li>다섯 페이지 : 한 페이지가 부족할때, 아이템 분류가 필요할 때 다섯 페이지(In-App Purchase)<br />
<img src="/assets/imgs/180405/blink_12.png" alt="" /><br />
<br />
<br /></li>
<li>백업/복원 : 아이템을 백업해뒀다가 필요할때 복원할 수 있는 기능</li>
<li>URL 정리 : 긴 URL을 간단한 키워드로 정리해주는 기능</li>
<li>단어 잘림방지 : 오른쪽 엣지에서 잘리는 단어를 음절 단위가 아니라 띄어쓰기를 기준으로 잘라주는 기능
<br />
<br /></li>
</ul>
<p>간단하게 입력하고 손쉽게 완료할 수 있는 기본 컨셉을 해치지 않기 위해 정말 필요하다고 생각되지 않으면 새로운 기능을 추가하지 않았고, 추가할 기능은 며칠씩 테스트하며 기존 방식에 잘 부합되는지 확인에 확인을 거쳤다. 그렇게 업데이트를 해온 지 어언 1년, 생산성 카테고리에서 자리를 잡아가는 Blink를 보면 괜히 뿌듯하다. 아이폰의 기본 기능과 디자인에 충실하면서 기본 기능에 충실한 메모 앱 Blink, 앞으로 더 많은 사용자들이 사용하면서 피드백을 들려주면 좋겠다.
<br />
<br />
<br /></p>
<h3 id="3-버그-이야기">3. 버그 이야기</h3>
<p>작년 가을, 심각한 버그가 발생했다. 앱을 실행하면 흰 화면만 뜨고 메인화면이 뜨지 않는 매우 심각한 버그였다. 여기저기 수소문했지만, 주변에서는 그 현상이 일어나는 기기를 찾을 수 없어 디버깅 할 수 없었고, 해결하는데 꽤 오랜 시간이 걸렸다. 잘 사용하던 사람들이 흰 화면을 호소하는 리뷰가 올라올 때마다 점점 말라갔다. 버그를 만들어내고 해결하지 못하는 개발자라니🤯 혹시나 하는 마음에 몇 번씩 수정 업데이트를 했지만 해결되지 않다가 AppDelegate의 Notification 관련 메서드를 수정하고 나서야 겨우 해결할 수 있었다. iOS10 일때는 문제가 없었는데 iOS11로 시스템이 업데이트 되면서 해당 메서드가 몇몇 디바이스에서 오류를 일으키는 것 같았다. <br />
그때를 생각하면 아직도 마음 한 구석이 위축된다ㅜ 전 세계에서 여러 사람이 사용하는 서비스에 당장 해결 할 수 없는 버그의 발생은 개발자인 나에게 자괴감과 함께 여러 가르침을 주고 떠났다. 테스트용으로 만드는 앱은 혼자 감당하면 되니까 괜찮지만 수많은 사람들이 사용하는 앱을 배포할 때는 한줄 한줄 고민해야 한다. 내 폰에서만 잘된다고 문제가 없다고 생각하면 안된다는 사실! 실제로 버그가 발생하면 밤새 머리를 쥐어짜며 살펴봐도 수만 줄의 코드 중에서 어느 녀석이 문제인지 알아내기란 쉽지 않다. 그러니 코드를 처음 작성할때 눈앞의 휴식을 생각하기 보단 정말 필요한 코드인지, 다른 기능과 충돌되지는 않는지 고민 해야한다…그래야하는데 말이다😔. <br />
그리고 버그가 없는 앱을 만드는 게 역시 제일 좋지만, 버그를 끝까지 해결하려는 자세 역시 매우 중요하다는 것을 깨달았다. 버그가 발생할 때마다(꽤 자주) 재촉하지 않고 늘 그 자리에서 함께 고민하고 기다려준 John, 고맙습니다 :)</p>
<p><br />
<a href="https://medium.com/@fuzzwaa_78918/blink-블링크-메모-앱-디자인-과정-72eef9289b33">John의 블링크 메모 앱 디자인 과정 읽으러 가기</a>
<br />
<br /></p>심플한 메모 앱, Blink 이야기 “당신은 메모를 잘 하는 사람입니까?” “아주 가끔은….?”똑똑한 Watson, 재빠른 Swift와 만나다 파트 12018-03-25T09:52:09+00:002018-03-25T09:52:09+00:00https://mijeongjeon.github.io/jekyll/update/2018/03/25/swift_meets_watson1<p><strong>파트1. 왓슨과 스위프트, 그 둘의 만남에 대하여</strong></p>
<p>내 예상보다 둘의 만남은 조금 더 빨랐다 🤭<br />
유명한 탐정 셜록의 조수와 동명인 IBM AI Watson과 Apple Swift의 만남.<br />
두 왓슨의 똑똑함은 이미 전세계가 알고있는 사실이며, Swift가 안정적이고 빠르다는것 역시 알만한 개발자들은 모두 알고 있지. 애플이 최근 AI 분야와 관련해 하드웨어와 소프트웨어를 열심히 개발 하고 있다는 것 또한.</p>
<p>그러던 어느 미세먼지 가득한 수요일, 애플에서 메일한통이 날아왔다.</p>
<p>CoreML이랑 Watson이 만났으니 네 앱을 한 층 더 똑똑하게 만들어보지 않겠냐고.</p>
<p><img src="/assets/imgs/180325/Screen Shot 2018-03-27 at 2.37.38 PM.png" alt="메일 이미지" /></p>
<p>새벽 5시에 날아온 메일은(나는 뭘하느라 깨어있었을까?) 잠이 들까말까하는 몽롱한 상태의 나를 깨우기에 충분히 매력적이었다. 간략히 나와있는 설명을 후다닥 읽고 <em>Learn more</em>를 클릭했다.</p>
<h2 id="ibm-watson-services-for-coreml"><a href="https://developer.apple.com/ibm/">IBM Watson Services for CoreML</a></h2>
<p>그들의 설명을 따르면 이러하다.</p>
<hr />
<h3 id="당신의-앱에-인공지능을-탑재하는-새로운-방법을-살펴보세요">“당신의 앱에 인공지능을 탑재하는 새로운 방법을 살펴보세요!”</h3>
<p><strong>Watson Services for CoreML을 사용하면 iPhone 및 iPad에서 강력한 Watson 기능을 사용하는 애플리케이션을 손쉽게 만들 수 있습니다. 게다가 Apple 용 IBM Cloud Developer Console을 사용해 CoreML용 Watson 서비스 및 다른 다양한 IBM Cloud 서비스를 사용할 수 있어요!</strong></p>
<hr />
<p>음!? <br />
여기까지 읽어서는 아직 잘 모르겠는걸? 🧐<br />
눈이 감기지만 조금 더 읽어봐야겠다.</p>
<hr />
<p><strong>Watson Services for CoreML을 활용하면 오프라인에서도 Watson 모델을 사용할 수 있는 iPhone, iPad 용 앱을 만들 수 있어요. Waton의 엄청난 기능을(이미지 분석 및 분류, 번역, 텍스트 <-> 음성 변환)이용해 손쉽게 모델을 만들 수 있는거죠. 이미 잘 구축되어있는 Watson 모델을 활용하거나, 원하는 모델을 직접 만들어 앱에 사용해보세요!</strong></p>
<p><strong>Watson은 이미지를 빠르고 정확하게 이해할 수 있으며 풍경, 사물, 얼굴, 색상, 음식 및 다양한 컨텐츠를 분석할 수 있습니다. 만일 맞춤형 모델이 필요하다면 자신만의 이미지를 활용해 맞춤형 이미지 분류 모델을 생성 할 수 있습니다.</strong></p>
<p><strong>그뿐만이 아닙니다! Watson Continuous Leraning을 활용하면 시간이 지남에 따라 지속적으로 학습하고, 더욱 향상되는 모델을 만들 수 있습니다.</strong></p>
<p><img src="/assets/imgs/180325/Screen Shot 2018-03-27 at 2.54.11 PM.png" alt="이미지" /></p>
<hr />
<p>우와! 둘의 만남이 이렇게 이루어지다니! 멋지다 멋져요! 👏🏻👏🏻👏🏻<br />
최근 CoreML에 굉장한 흥미를 가지기 시작했기에 나는 이미지와 글을 보고 굉장히 큰 감명을 받고서 곧 바로! 깊은 잠에 빠졌다😪😪😪. 꿈에서 뭔가 만들었던거 같은데;; <br />
잠에서 깨어나 반쯤 뜬 눈으로 다시 메일함에 들어가 둘의 만남이 꿈이 아니었음을 확인했다. 그리고 노트북을 열어 IBM에 접속했다. 따끈따끈한 신상 기능을 활용해 봐야지~</p>
<p>다음편에 계속…</p>파트1. 왓슨과 스위프트, 그 둘의 만남에 대하여한편의 동화 같지만 읽어보면 별거 없는 미르뱅 이야기2018-03-22T09:52:09+00:002018-03-22T09:52:09+00:00https://mijeongjeon.github.io/jekyll/update/2018/03/22/the_first_story_of_mj<p>이 이야기는 이렇게 시작합니다.</p>
<p>아주 먼 옛날, 금과 은을 잘게 잘게 쪼개 나노 물질을 만들어 팔아 살아가던 공대생 미르뱅이 살고 있었어요. 마을에서 유명한 게으름뱅이었던 미르뱅은 어느 여름, 금과 은을 모두 내려놓고 그간 모은 돈을 모아 세계여행을 떠났어요. 미르뱅은 세계 각 지역의 특산품과 전통주를 먹고 마시며 한량 생활을 만끽했죠. 낯선 곳을 다니며 가끔 멈춰서 아름다운 풍경에 감탄하고, 가끔 벤치에 앉아 시를 읊조리고, 가끔 아닌 자주 술에 취해 인생과 삶에 대해 고민했어요. 그러다 정신을 차려보니 여행을 시작할 때의 따스한 여름 햇살은 모두 사라지고 시린 겨울바람이 다가온 걸 깨달았죠. 물론 전 재산은 이미 없어진 지 오래였구요. 미르뱅은 아쉬움을 뒤로하고 오돌오돌 떨며 집으로 돌아왔어요. 집에 돌아와보니 마을 사람들은 그동안 자기 길을 찾아 잘 살아가고있었죠. 하지만 미르뱅은 아름다운 여행의 기억에 갇혀 일도 공부도 하지 않은 채 점점 더 게으르고 맹해져 갔어요.</p>
<p><em>이년 후…</em></p>
<p>여느날 처럼 미르뱅은 핸드폰으로 지난 여행 사진을 보고 있었는데, 여행 사진을 정리하는 애플리케이션이 있으면 좋겠다고 생각했어요. 원하는 걸 찾기 위해 A스토어를 열심히 돌아다녔지만 미르뱅 원하는 건 찾을 수 없었어요. 아쉬운 마음에 미르뱅은 스스로 만들어야겠다고 결심했죠. 그 후 겨우겨우 집 밖으로 나가 개발을 공부하기 시작했어요. 게으른 태생에 비해 미르뱅은 나름 열심히 공부했고, 결국 원하던 애플리케이션도 만들어냈어요. 미르뱅은 그렇게 새로운 삶을 살아가기 시작했어요. 그러던 어느 날 진짜 개발자들이 모여사는 마을에 방문하게 되었죠. 그곳에서 만난 친절한 진짜 개발자들이 건네주는 명함을 받았지만, 소속회사도, 직함도, 사무실도, 명함도 없어 멀뚱멀뚱 서 있던 미르뱅은 상대의 의문스러운 표정을 마주하다 자기도 모르게 이렇게 말을 꺼냈어요.</p>
<h3 id="안녕하세요-저는-모바일-개발자-미르뱅입니다">“안녕하세요, 저는 모바일 개발자 미르뱅입니다.”</h3>
<p>“안녕하세요, 저는 게으름뱅이 한량 미르뱅입니다.” 가 아니라!!</p>
<p>그렇습니다. 미르뱅은 자신을 이렇게 소개하면서 모바일 개발자가 되었죠. 그리고 이왕 이렇게 된거 진짜 모바일 개발자가 되기로 합니다. 예전처럼 아드리아해를 바라보고 앉아 개발할 수 있지 않을까 꿈꾸면서.</p>
<p>하지만 여전히 미르뱅은 너무도 게을러서 그 꿈이 쉽게 이루어지지 않을 것을 잘 알고 있습니다. 그래서 블로그에 글을 올려보기로했죠. 공부한걸 잊지않기 위해서, 스스로 개발자라고 말하는게 부끄럽지 않으려고. 조금씩 조금씩 하다보면 미르뱅도 멋진 개발자가 될 수 있겠죠 :)</p>
<p>부디 미르뱅의 이야기가 해피엔딩으로 끝나길 기원해주세요.</p>이 이야기는 이렇게 시작합니다.