🐿️Nuxt 4 기반의 차세대 커뮤니티 빌더

The Next Evolution
of Community

NUBO는 TSBOARD의 빠른 속도를 계승하면서도 스킨 시스템과 SEO 최적화를 갖춘 고성능 커뮤니티 빌더입니다

cover image

NUBO 프로젝트 중간 점검

0 0 38

요즘 주말 시간 대부분을 NUBO 프로젝트 개발에 몰두하느라 시간이 어떻게 지나가는지도 모르겠습니다. 😭꽤나 많이 달려온 것 같은데, 이제 관리 화면 작업 및 설치 화면을 전면적으로 개편하면 될 듯 합니다.중간 점검도 할 겸, 오랜 시간 방치한 블로그에 쌓인 먼지도 치울 겸 간단히 글로 정리해 보고자 합니다. NUBO의 시작 : SSRNUBO는 TSBOARD 프로젝트를 직접적으로 계승합니다. DB 스키마도 완전히 동일하게 사용하며, GOAPI 백엔드의 경우 이제는 NUBO 위주로 업데이트가 되고 있지만, TSBOARD 시절과 비교하면 완전히 새롭게 변경되거나 하진 않았습니다. 가장 많이 변경된 부분은 바로 프론트엔드인데, TSBOARD를 긱뉴스에서 선보인 후로 가장 많은 피드백을 받았던 SSR(Server Side Rendering) 지원을 하기 위해서 시작한 프로젝트입니다.  처음에는 사실 내키지 않았습니다. 아무리 모던 웹 개발이 복잡해지고 어려워진다 하더라도, 프론트엔드에 이 정도까지 노력을 기울이는 게 가당찮아 보였기 때문입니다. 예전에 php4 시절에 했던 풀스택 개발 (그 때는 모든 웹 개발이 풀스택이었고 그게 당연했습니다) 보다 오늘날의 프론트엔드 개발이 더 복잡해지고 어려워졌습니다. 그런 상황에서 TSBOARD의 설계에서 가장 중요한 결정 사항이었던 SPA(Single Page Application) 구조를 버리고 SSR로 변환하는 게 두렵기도 했고, 괜한 고생길을 가는 거 아닌가 하는 우려도 있었습니다. 하지만 꽤나 많은 분들이 SSR로의 전환을 권해주시기도 했고, 결정적으로 TSBOARD 사이트의 컨텐츠 노출이나 게시글 업데이트 등이 구글에서 제대로 이뤄지지 않는 점을 목도하면서 백엔드 교체에 이어 프론트엔드 교체도 단행하게 되었습니다. 개발 스택 선택개발 스택은 TSBOARD 프로젝트를 진행하면서도 꽤나 많이 바뀌었습니다. 애초에 정했던 건, 지금은 앤트로픽에 인수된 Bun 런타임 기반의 백엔드를 구성하고, 프론트엔드는 Vuetify를 중심으로 해서 SPA 기반으로 페이지를 구성하는 것이었습니다. 당시에 웹 프레임워크로 선택한 ElysiaJS의 경우 꽤나 빠른 동작 속도를 보여주기도 했고, 개발 편의성도 높았기 때문에 TSBOARD의 초반 성능은 제 기준에서 나름 훌륭했습니다. 원래 프로젝트의 목표가, TypeScript 라는 꽤나 멋진 언어를 처음 배워보면서 이 언어만으로 풀스택 웹개발을 해보자! 였기 때문에 프로젝트 이름도 TS를 따와서 TSBOARD가 된 것이었습니다. 여하간 문제 없이 1.0 버전까지 Bun 런타임 기반으로 쭈욱 이어질 줄 알았건만, 생각지도 못하게 당시 Bun 런타임의 가상 CPU 버그 문제에 발목이 잡히면서 백엔드를 교체하자는 결정을 내리게 됩니다. 그 때 당시에는 정말 미친 결정이었지만, 지금 생각해보면 너무나도 좋았던 Go 언어로 백엔드를 다시 개발한다는 결정을 한 후에 열심히 Go 언어를 배워가면서 기존에 TypeScript로 작성한 백엔드 코드를 변환하기 시작했습니다. 그리고 1.0 버전 공개 시점에 맞춰서 백엔드 교체까지 하고 TSBOARD를 선보일 수 있었습니다.  이제 SPA 에서 SSR 방식으로 프론트엔드를 렌더링 해야 하니, 당연하게도 Nuxt로의 전환을 가장 먼저 결정하였습니다. React를 썼었다면 당연히 Next.js로 아마 갔을테지만, 저는 Vue3을 꽤나 만족하면서 썼고 이제와서 모든 걸 버리고 React로 변경하는 건 생각하고 싶지 않았습니다. 일단 Nuxt로 결정하면서, 이어서 결정해야 하는 건 UI 라이브러리였는데 여기서는 살짝 도박을 하게 되었습니다. 바로 잘 쓰던 Vuetify를 떠나 Shadcn-vue를 선택한 것입니다.  Shadcn-vue로 교체한 이유는, 이 UI 라이브러리가 커스텀의 범위가 굉장히 넓고 tailwindcss를 배워서 써먹기에 꽤나 괜찮아 보였기 때문입니다. 접근성을 고려한 점도 물론 있습니다만, 커스텀과 tailwindcss가 정말로 컸습니다. 그리고 예시 UI 컴포넌트들도 꽤나 제 취향의 심플함이 반영되어 있었구요. Nuxt에 적응하는 것과 더불어서 shadcn-vue, tailwindcss를 처음부터 새로 배워 나가면서 가만 생각해보니, 이정도까지 변경된 걸 그냥 TSBOARD 2.0으로 퉁칠 수 있을까? 하는 점이었습니다. TSBOARD 2.0이 아닌 이유처음에는 프로젝트명에 대해서 크게 고민하지 않았습니다. 그냥 TSBOARD v1.5라고 하자, 아니다 이 정도까지 바뀐거면 2.0 해도 되겠다. 그냥 TSBOARD 2.0라고 하자, 등등 여러 생각들이 떠올랐습니다.  하지만 계속 생각하면 할수록, 처음에 TSBOARD를 만들면서 품었던 계획과 목표, 그리고 수단이 어느 덧 많이 바뀐 것 같다는 생각이 점점 커지기 시작했습니다. 가장 핵심적인 이유는, 더 이상 TypeScript 단일 언어로 개발되는 프로젝트가 아니라는 점입니다. 이미 백엔드는 TSBOARD 시절에 Go 언어로 전환했고, 프론트엔드의 경우 TSBOARD는 그나마 별도의 프레임워크라고 할만한 게 없었습니다만 이제는 Nuxt라는 것이 핵심이 되었습니다. 처음에 TSBOARD라는 소박한 이름에 품었던 내용들이 어느 새 많이 희석된 것입니다. 그래서 이참에 새로 이름 하나 지어줘야겠다, 라는 생각이 들어서 TSBOARD 2.0이 아닌 NUBO라는, 다소 생뚱맞은 이름을 선택하게 됩니다. NUBO : 차세대 커뮤니티 빌더프로젝트 이름에 Board가 들어간 건 아주 오랜 옛날, 제로보드와 그누보드가 웹 세상을 호령하던 그 시절의 향수 때문이기도 했고 또 이전에 진행하였던 GR Board라는, 이제는 잊혀진 프로젝트에 대한 추억 때문이기도 했습니다. 그러나 이 프로젝트가 PHP 시절에 개발된 게시판이 아니라 사이트 자체를 빌드하고 더 큰 규모의 트래픽을 감당하도록 설계된 점, 그리고 확장성까지 고려하면서 나름 많은 고민을 안고 진행하는 점을 감안하여 이름을 새롭게 짓고 싶었습니다. 여러 아이디어들이 있었지만, 작명 센스가 정말 없구나 하는 한탄과 함께 Nuxt 와 TSBOARD의 알파벳들을 적당히 조합해서 NUBO라고 이름을 지었습니다. A New Unified Board 라는 설명 문구가 있긴 합니다만, 이거는 나중에 가져다 붙인거고 실제 NUBO는 무슨 축약어 같은 게 아니라 그냥 개똥이 처럼 지은 이름입니다. 이름에 대한 여러 해석들은 나중에 생각하기로 하고, 이 자칭 차세대 커뮤니티 빌더가 가져야 하는 가장 큰 특색을 무엇이 되어야할지 고민을 하게 되었습니다. NUBO의 차별화 : 스킨 시스템TSBOARD부터 NUBO에 이르기까지, 제가 웹 개발을 하면서 늘 가지고 있던 추억은 제로보드4와 그누보드5 시절에 만들던 스킨이었습니다. 지금은 오히려 스킨 보다는 테마나 템플릿이라는 용어를 많이 쓰기도 하고, 디자인 시스템을 굳이 바꾸거나 하지 않는 경우도 많아진 것 같습니다만, 당시에 스킨 시스템은 지금 돌이켜봐도 굉장히 혁신적이었고 생태계를 창조할 수 있는 힘이 있었습니다. 제가 스킨 제작자로 당시에 아주 조촐한 이름을 얻었던 기억이 있기 때문인지, TSBOARD를 개발할 때도 스킨 시스템을 꼭 넣고 싶다는 생각이 간절했었습니다. 다만 그 때는 Vue3나 Vuetify같은 것에 허덕이던 시절이었고, PHP가 사라진 웹 세상에서 덩그러니 혼자 방황하던 시절이라 스킨까지 고민하진 못했었습니다. 그냥 프로젝트 자체를 내려 받아서 다른 누군가가 필요하면 본인의 디자인 감각에 맞게 고쳐 쓰시겠지, 이 정도만 생각 했었죠. 그러나 저에게 부족한 건 작명 센스 뿐만이 아니라는 점이 점점 더 명확해지면서, NUBO 프로젝트에서는 반드시 스킨 시스템을 넣겠다는 각오로 열심히 고민하면서 개발을 진행하게 됩니다. 그러다 드디어 Provide & Inject 방식으로 디자인과 로직을 비교적 깔끔하게 분리할 수 있는 방안을 찾게 되면서 NUBO의 핵심적인 차별화 기능으로 모던 웹에서도 스킨 시스템을 도입할 수 있게 되었습니다. NUBO에서는 nubo-basic-board, nubo-basic-login 처럼 각각의 기능들을 표현할 수 있는 기본 스킨들이 모두 제공됩니다. 크게는 레이아웃 디자인부터 작게는 에러 메시지 출력 페이지까지 모든 페이지들은 스킨으로 표현됩니다. 아직 개발을 시작하진 않았습니다만, 관리 화면도 마찬가지로 스킨으로 표현되므로 저보다 디자인 감각이 좋으신 대부분의 개발자분들이 더 멋진 대시보드와 UX로 무장한 관리자 화면용 스킨을 개발 하실 수도 있습니다. Gofiber v3 기반의 고성능 백엔드 엔진이 이제 더 많은 일들을 해주고, 프론트엔드 역시 SEO(Search Engine Optimization)가 필요한 페이지들은 SSR 기반으로 렌더링된 페이지가 나오도록 해서 클라이언트와 부담을 나눠서 짊어지도록 할 수 있습니다. 또한 TSBOARD 시절에는 Bun 런타임이 우선이었지만 지금은 Node.js가 기본이고 Bun과 Deno가 선택 옵션이므로 더 보통의 환경에서 서버를 운용 하실 수 있게 됩니다. 곧 소개하겠습니다과거 PHP 시절의 향수와 현재의 모던 웹 개발이 함께하는 NUBO, 곧 정식으로 소개할 날이 올텐데 가능하면 빨리 소개해 드리고 싶습니다. 😊 어서 다른 개발자분들의 피드백들도 받아보고 싶네요… 😆

tsboard sqlite + go whails 로 포팅한 독립 어플리케이션

1 1 96

tsboard sqlite + go whails 로 포팅한 독립 어플리케이션만든지는 몇일 됐습니다. 그런데 제가 하려고 했던건 다른 일이라서 여기에 글을 남길까 말까 오랜시간 고민했습니다. 아주 작은 출판쪽 ERP를 만들다 보니 어플리케이션이 필요하고 게시판도 필요해서 검토중에 GOAPI 가 마음에 들어서 일단 테스트로 포팅해봤습니다.잘되어있는 구조라서 바꿀건 mysql →sqlite , duckdb 였고 수정할 사항이 꽤 있었는데 일단 얼추 동작은 하게 만들고 원래 해야할 다른 일이 있어서 만들어주신 GOAPI 를 활용하고 있습니다. 속도와 안정성은 GO가 정말 좋은거 같습니다. 원래 프로젝트는 Rust 였지만 그래도 Tauri 패키징에서 윈도우 인스톨러 문제 때문에 주저하고 있었습니다.참고로 현재 프로젝트는 내부 서버겸 내부 게시판으로 돌려보는 것인데 P2P로 다른 원격지에 DB를 보내서 매일매일 작업 일계표 진행하는 프로젝트로 작업지시서 출판사←>창고 남의 회사에 주문 DB를 넣고 받는 형태입니다. 시리니 님의 프로젝트를 응원하면서 덕분에 이런 프로젝트하는 사람도 있다고 남기고 싶었습니다.참고로 에디터 유형은 몇가지 더 만들어 주시면 커뮤니티 활성화 하는데 도움이 될거 같습니다. (TSBOARD의 활용성이 작은 게시판이 좋기는 하지만 네이버카페, 일반 게시판 형태가 있으면 어떤 버튼을 어디서 찾아야 하는지 모드를 나눠 직관적인 테마를 적용하면 더 좋을거 같습니다.)
cover image

코딩의 종말? 바이브 코딩?

0 0 74

아주 간만에 글을 씁니다. 매번 글 쓰고 싶은 주제는 많았는데 시간이 없다는 아주 손쉬운 핑계로 글을 남기지 못하고 그냥 지나가게 되는 것 같습니다. 생각해보면 쓰다보니 계속 길어지고 그러다보니 다듬어야 하고 또 그게 귀찮아서 결국 안쓰는 악순환이 오는 것 같습니다. 그래서 오늘부터는 (언제까지 가능할지 모르겠지만) 나름대로 글자 수 제한 같은 게 있다고 상정하고 간단히 생각을 정리해 보려고 합니다.코딩의 종말, 대 바이브 코딩 시대코딩이라는 작업도, 프로그래머라는 직업도 사라지게 될 것이다는 주장은 계속 있었습니다. 예전에는 쉘 스크립트로, 위지윅 에디터로, 노코드 프로그래밍 등으로 다양한 종말론이 나왔죠. 이번에는 그 때와 달리 AI라는 아주 거스르기 어려운 트렌드와 이전과는 비교하기 어려운 막강한 컴퓨팅 파워를 등에 업고서 진짜 코딩의 종말, 그리고 입코딩…이 아닌 프롬프트 코딩 시대가 열렸다고 아주 난리입니다. 실제로 빅테크에서도 해고가 많이 이뤄지고 있고, 앞으로 더 대규모의 투자 전쟁이 지속될수록 핵심 AI 엔지니어들만 소수 필요하고 나머지 프로그래머들은 점차 사라지게 될거라는 전망이 우세합니다.저도 GPT 선생님의 도움으로 예전이라면 아마도 상당한 시행착오를 겪어야 했을 시간들을 굉장히 줄일 수 있었습니다. 생산성이 말 그대로 폭발적으로 향상되는 것 같은 느낌은 코딩이라는 작업을 할 때마다 매번 느끼는 중입니다. 최근 뉴스에서 신입 개발자를 더 이상 채용하지 않는다는 기사들을 볼 때마다 신입 개발자보다 월 $200~$300 정도의 비용으로 기존 개발자들이 더 높은 생산성을 달성하는 게 이득이라는 계산이 있겠구나 하는 생각도 들었습니다.그렇지만 또 한 편으로는, 기존의 개발자들이 얻을 수 있었던 폭발적인 생산성 향상이나, 기존에는 개인 단위의 개발 리소스로는 만들기 어려운 것들을 만들어볼 수 있는 시대가 된 것은 맞지만 아예 개발자들을 대체하는 게 정말로 가능한가? 라는 나름의 의구심이 드는 것도 사실입니다. 특히나 사내에서 최근에 RAG + LLM 방식으로 사내 코드들을 빠르게 검색하고 튜닝 등을 할 수 있는 플랫폼을 작게 나마 만들어보면서, 그리고 AI가 저 대신 작성해준 코드들이 언뜻 잘되는 것처럼 보이다가, 어느 시점이 지나면 계속해서 실패하고 기본적인 부분들도 놓치고 코드를 다시 이상하게 만드는 것들을 보면서 그런 생각이 더 강해졌습니다. 아무것도 몰라도 괜찮아? 글쎄?저는 바이브 코딩이라는 게 마치 운전을 전혀 할 줄 몰라도 자율 주행 자동차만 있으면 어디로든 갈 수 있다는 말처럼 들렸습니다. 물론, 지금의 테슬라 자동차도 FSD를 통해서 주차장부터 운전자에게 스스로 찾아오기도 하고 때로는 기나긴 거리를 사람의 개입 없이 안전하게 운행하기도 합니다. 앞으로 기술이 더 발전하게 되면 지금의 로보 택시와 같은 것들이 더 당연한 시대가 오기도 하겠죠.그렇지만 적어도 지금 시대는, 최소한 운전은 할 줄 알아야 합니다. 운전 면허도 없고 운전을 한 번도 해본 적이 없이 자율 주행 자동차에 탑승하고 어디론가 가는 건, 그렇게 갈 수는 있더라도 그것이 더 안전할지, 더 효율적인지 모릅니다. 만약 예외 상황이 발생하면? 그 땐 알고리즘이 아니라 하늘에게 본인의 운명을 맡겨야 하겠죠.바이브 코딩이라는 것도 마찬가지입니다. 기획력이 좋은데 프로그래밍은 할 줄 모르는 사람에겐 이 바이브 코딩이 일종의 해 볼만한 프로토 타이핑 정도는 될 수 있습니다. 그러나 바이브 코딩만 진행해서 상용 솔루션을 출시한다? 이건 또 다른 문제겠죠. 분명 어느 시점까지는 꽤 괜찮게 동작할 겁니다. 그러나 어느 규모를 넘어서기 시작하면 분명히 문제가 생깁니다. 눈에 보이는 단순한 버그 같은 건 차라리 LLM이 잘 잡아줄텐데, 근본적으로 설명하기 어려운 미묘한 설계상의 오류나 혹은 코드의 동작 방식에 대한 개선에 집중하다가 전체 솔루션의 본질과 점점 멀어지거나 하는 문제가 생길 수 있습니다. 그럴 땐 사람이 개입해서 바로 잡아야 할테고, 그러한 개입을 완전히 0으로 만들 순 없을 겁니다.이런 때 일수록 기본으로분명 큰 변화가, 그것도 스마트폰 시대와는 또 다른 근본적인 변화가 찾아왔습니다. 이제 AI라는 것은 우리의 일상 깊숙한 곳까지 이미 영향을 미치고 있는 상황입니다. 대 생산성 시대이기도 하고, 바이브 코딩을 필두로 한 프로그래머의 멸종이 공공연한 사실처럼 언급되는 시대이기도 합니다. 그러나, 저는 매번 이런 논의가 있을 때마다 그럼에도 불구하고 프로그래머는 사라지지 않고 AI가 모든 직업을 대체하지도 않을 뿐더러 결국은 이런 저런 논란에 휩쓸리지 않고, 자신만의 기본을 탄탄히 다지고 새로운 기술들을 잘 받아들인 분들이 승리자가 된다는 것을 이젠 알고 있습니다. 상대적으로 새로운 기술을 잘 이해하고 받아들이면서도, 여전히 기본기가 탄탄한 사람들이 오히려 시간이 지날수록 더 가치가 높아질거라 생각합니다.글이 또 길어지는 것 같아서 이쯤에서 마무리 하며… 바이브 코딩이나 MCP를 통해서 여러 멋진 사례들에 감명 받은 적도 적잖아 있긴 했습니다만, 지휘자 없는 오케스트라가 없는 것처럼, AI 혼자서 처음 목표 하나만 가지고 제대로 된 제품을 만들 수 있을 거라고는 생각하지 않습니다. 스스로를 피아니스트, 바이올리니스트로 제한 시키지 말고, 지휘자이면서 동시에 피아니스트라 생각해 보면 어떨까요?
cover image

구글 플레이 스토어에 앱 출시한 후기

0 0 89

TSBOARD를 만들면서, 언젠가 커뮤니티 사이트에 걸맞는 앱도 하나쯤 있으면 좋겠다는 생각을 종종 했었습니다. 그리고 몇 달간의 학습 겸 개발을 진행하고서 마침내 구글 플레이 스토어에 앱을 출시 하였습니다. 앱도, TSBOARD의 여정도 이제 시작이라는 느낌입니다만, 그럼에도 이 정도에서 한 번쯤은 후기를 한 번 남겨보는 것도 좋을 것 같아 끄적여 봅니다.구글 개발자 신원 확인앱 출시에 있어서 가장 큰 난관은 앱의 산적했던 버그들이 아니라, 바로 저에 대한 신원 확인이었습니다. 저의 경우 아주 오래전에 구글 개발자로 등록한 이력이 있었으나, 거의 등록만 해두고 별다른 활동을 하지 않았었기 때문에 중간에 있었던 강화된 신원 확인 절차를 진행 하지 않았습니다. 그러다보니 이 신원 확인 절차가 정말로 생소했습니다.개발자 신원 확인을 위해서는 개발자의 이름과 주소가 명시된 공문서를 pdf 형태로 등록해야 합니다. 가이드를 보면 고지서 같은거나 정부에서 발행한 지로 영수증 같은 걸 사진으로 찍어서 PDF 변환 후 업로드하면 되는 것처럼 나와 있는데, 문제는 사진의 경우 글씨가 또렷해야하고, 문서의 꼭지점 부분이 명확하게 나와야 하며, 결정적으로 1MB를 넘어선 안된다는 것입니다. 제가 집으로 날아온 고지서 여러 장을 사진으로 찍고 다시 줄여서 PDF로 만들어 보았습니다만, 대부분 1MB는 훌쩍 넘었고, 그마저도 크기를 억지로 맞출 경우 글씨가 굉장히 흐릿하게 나타나는 문제가 있었습니다. 구글같은 기업에서 문서들을 일일히 사람 눈으로 확인하거나 하진 않을테니, 당연히 기계가 문서를 판독할텐데 안타깝게도 성능이 그리 좋지 못한 것 같더라구요. 한 3번 정도 반려를 먹었습니다. 한 번은 집 주소가 나오지 않은 고지서라서, 또 한 번은 문서가 너무 흐릿해서, 마지막으로는 둘 다 해당되어 반려되었던 것 같습니다. 정말 이 때는 엄청 빡치긴 하더라구요. 사실 가장 큰 불만은, 구글에 제가 유튜브 프리미엄이나 구글 포토 등으로 내는 돈이 있을텐데 그건 그거고 개발자 신원은 상관없이 까다롭게 확인하는 것이었습니다. 마지막으로 시도했던 것이 은행 앱을 통해서 발급받은 원천징수 영수증이었습니다. 해당 영수증을 살펴보니, 제 이름과 주소가 명확하게 나와 있었고, 나름 은행에서 발급했다는 인장 같은 것도 있는데다 결정적으로 이 문서는 사진을 찍을 필요 없이 바로 PDF로 업로드가 가능했습니다. 물론 1MB 이하의 크기로 업로드 규격도 만족합니다. 이 문서를 업로드하면서 비로소 개발자 신원 확인을 받을 수 있었습니다. 통상 신원 확인에 성공하든 실패하든 업로드 시점으로부터 하루 정도 소요되었던 것 같은데, 이걸 4번 정도 하다보니까 이러다가 플레이 스토어에 출시도 못해보고 끝나는 거 아닌가 하는 걱정도 사실 많이 했었습니다.구글 계정으로 로그인앱을 개발하다보니 웹에서 이미 구현했던 OAuth2 로그인 기능도 약간 새로운 부분이 있었습니다. 안드로이드 앱을 처음 만들어서 저만 조금 어려웠던 것일지도 모르겠습니다. 구글 계정으로 로그인을 구현하려면, 구글 개발자 콘솔에서 사용자 인증 부분에 안드로이드 앱에 등록되어 있는 SHA-1 디지털 지문을 등록해줘야 합니다. 이 SHA-1 코드는 안드로이드 스튜디오나 콘솔에서 keytool 도구를 이용하여 쉽게 만들 수 있습니다. 처음에는 당연히 디버그 모드로 테스트를 해야 하니까, 구글 개발자 콘솔에 Debug 모드에서 생성한 SHA-1 디지털 지문만 등록했었습니다. 그러면서 한참동안 디버그 모드로만 개발을 진행하다보니, 정작 출시 시점에서는 Release 모드에서 생성한 SHA-1 디지털 지문 등록을 까먹은 겁니다. 그래서 당연히 릴리즈 모드에서는 구글 로그인을 시도하면 NoCredentialException 예외가 발생하고, 하필 제가 그 때 예외 처리를 제대로 안해둬서 앱이 강제로 종료되는 문제가 생겼었습니다. 다행히 원인을 빨리 파악해서 부랴부랴 Release 모드에서 SHA-1 지문을 다시 구글 개발자 콘솔에 추가로 등록하고, 문제를 해결했다고 생각했습니다.그러나 생각지도 못하게, 구글 플레이 스토어에 등록한 앱을 내려 받고서 다시 테스트를 해보니 이번에는 예외 처리가 되어서 죽진 않았지만 여전히 로그인에 실패하는 겁니다. 이 때 살짝 멘붕이 왔었습니다. 아니, 분명히 Debug 도 Release도 모두 SHA-1 디지털 지문을 구글 개발자 콘솔에 등록했는데? 혹시 Debug 모드는 지우고 하나만 남겨뒀어야 하나? 별에 별 생각을 다 하다가, 뒤늦게 구글 플레이 스토어가 앱에 또 다른 SHA-1 디지털 지문을 이식한다는 걸 알게 되었습니다. 그러니까, 구글 개발자 콘솔에 사용자 인증 부분에서 제가 등록해둬야 하는 디지털 지문이 총 3개가 되는 겁니다. Debug, Release 그리고 구글 플레이 스토어에서 생성한 SHA-1 지문까지.구글 개발자 콘솔 말고, 구글 플레이 콘솔에 들어가면 테스트 및 출시 > 설정 > 앱 서명 부분에서 SHA-1 디지털 지문을 만날 수 있었습니다. 이걸 다시 구글 개발자 콘솔에 또 등록을 해줬어야 했던 겁니다. 처음 하다보니 구글 계정으로 로그인 같은 간단한 기능도 사실 좀 어려웠습니다. 다행히 지금은 잘 동작합니다만, 그냥 무작정 이것 저것 하다보니 이런 시행착오가 많았습니다.라이브러리 호환성 맞추기TSBOARD 프로젝트를 처음 시작할 때 조금 어려웠던 게 NPM을 통한 라이브러리들 내려받기 였습니다. 왜냐면 생각보다 너무 많은 라이브러리들을 받아야 하는데다 가끔씩 버전 호환성 이슈를 만나면 해결이 난감했기 때문입니다. 다행히 NPM도 발전하고, 저도 내성이 생기면서부터는 프론트엔드나 백엔드 프로젝트 모두에서 큰 어려움 없이 개발을 할 수 있었습니다. 하지만 안드로이드 앱의 경우는, 뭔가 차원이 다른 어려움이 있었습니다. 일단 제가 모르는 걸지도 모르겠지만, 필요한 라이브러리들을 버전까지 명시해서 build.gradle.kts 파일에 기록해야 했습니다. 만약 제가 명시한 Android SDK 버전에서 지원이 안되면, 다시 라이브러리의 버전을 내리면서 어떤 버전을 써야 하는지 직접 찾아야 하는 문제가 있었습니다. NPM이 정말 혁신적인 패키지 매니저였구나, 하고 느끼면서도 왜 안드로이드에서는 저런 게 없지? 하는 생각도 많이 들었습니다.또 까다로운 문제라고 하면, 생각보다 Deprecated가 빨리 된다는 점입니다. Material 3 컴포즈 관련 라이브러리들은 메소드 이름부터 사용법까지 꽤나 드라마틱하게 변경되고 있었습니다. 물론 Deprecated된 메소드들은 대체제를 IDE에서 문서로 쉽게 확인할 수 있기 때문에 사실 너무 어렵다거나 한 건 아니지만, 그래도 처음 앱을 만들어보는 입장에서는 여간 까다로운 게 아니었습니다. 라이브러리들의 버전을 함부로 올리지 말라는 조언이 왜 나온 것인지 알 수 있었네요. 웹과는 다른 UX앱을 만들면서, 구글이 제공하는 Material Design에 대해서 좀 더 내용을 확인해보고, 권장하는 UX가 어떤 것인지를 되새기면서 작업을 하고자 했습니다. TSBOARD는 물론 모바일 브라우저에서도 스크린 크기에 맞춰 화면을 훌륭하게 구성해서 보여주긴 하지만, 아무래도 손가락으로 터치한다는 개념 보다는 마우스 포인터로 클릭한다는 개념이 좀 더 녹아져 있는 디자인이었습니다. 그래서 이왕 안드로이드 앱을 만드는 거라면, 좀 더 터치에 적합한 UI로 구성해야겠다는 생각을 했었습니다. 그러면서 https://material-foundation.github.io/material-theme-builder/ 이 사이트에서 컬러 셋부터 시작해서 디자인 구성까지 많은 걸 참조했습니다. Material Design에서 제공하는 기본적인 요소들과 컬러들만 가지고도 이처럼 훌륭하게 디자인을 할 수 있다면, 굳이 웹에서 했던 디자인을 답습할 필요 없이 처음부터 다시 고민해서 만들어 보는 것도 나쁘진 않겠다는 확신을 가지고 앱을 디자인 했었습니다. 그 결과 좀 더 단순하고 정갈한, 아주 기본에 충실한 디자인으로 앱을 만들 수 있었습니다.조금 아쉬운 건, 나름의 고민과 노력으로 어떻게든 해보긴 했습니다만 그럼에도 상용 앱들이 보여주는 훌륭한 UI와 사용자 친화적인 UX에는 아직 따라가지 못한다는 점입니다. 이 점은 훌륭한 UX로 손꼽히는 토스 앱 같은 걸 참조해서 저도 계속 개선해야 하겠습니다.끝이 아닌 시작, 조금씩 그러나 꾸준히TSBOARD도 마찬가지입니다만, 이번 안드로이드 앱 역시도 조금씩 하지만 꾸준히 기능들을 개선하고 UX를 다듬어 나가고자 합니다. 사용자가 많진 않지만, 어쨌든 제가 즐겁게 쓰고 있으니 제가 편하게 쓰기 위해서라도 점진적으로 개선해 보고자 합니다. 처음부터 잘 할 수는 없으니, 꾸준히 노력해서 개선하는 것이라도 해봐야겠지요. https://play.google.com/store/apps/details?id=me.sensta구글 플레이 스토어에서 Sensta를 검색하시면 카메라를 앞에 둔 다람쥐를 만나 보실 수 있습니다. 우여곡절이 많은 앱입니다만, 안드로이드 스마트폰을 쓰시고 사진 좋아하신다면 한 번 사용해 보시고, 의견도 부탁드립니다.
cover image

TSBOARD v1.0.5 업데이트 안내!

1 0 169

안녕하세요! TSBOARD를 개발하고 있는 시리니입니다.TSBOARD 기반으로 만들어진 커뮤니티를 위한 안드로이드 전용 앱, SENSTA의 공개가 이제 코 앞으로 다가왔습니다.Kotlin 언어와 함께한 시간들을 마무리하면서, 앱에서 필요했던 기능들과 앱에 이미 구현된 기능들을 이번 업데이트에서아래와 같이 반영해 보았습니다.[Backend - GOAPI]안드로이드 네이티브 앱 SENSTA 와의 원할한 연동을 위해 아래 사항들이 반영되었습니다.id_token 값을 받으면 구글 OAuth2 API로 인증 후 사용자 정보를 JSON 형태로 바로 반환하도록 추가하였습니다.채팅 메시지를 저장할 때 가끔 처리되지 않던 nil pointer exception 문제를 수정하였습니다.앱에서 사용자 정보를 요청할 때 사용자 고유 번호를 생략하던 문제를 수정하였습니다.삭제 처리된 댓글은 댓글 개수에 반영하지 않도록 수정하였습니다.채팅 메시지를 받으면 중복 여부를 검사하지 않고, 매번 새 알림이 되도록 변경하였습니다.최근 사용된 해시태그 목록을 조회하는 기능을 추가하였습니다.작성자명, 분류명 검색 시 부분 문자열로 검색해도 되도록 개선하였습니다.첨부 이미지에 대해서 AI가 설명한 내용으로 게시글을 검색하는 기능을 추가하였습니다.갤러리 게시판 좌측 하단의 검색에서도 이제 이미지 항목으로 검색이 가능합니다.홈화면 상단 전체 검색에서도 이미지로 검색이 가능합니다.[Frontend - TSBOARD]홈 화면에서 현재 로그인 상태일 경우 액세스 토큰을 갱신합니다.구글 및 외부 CDN으로 사용하던 폰트들을 서버에서 직접 제공하는 방식으로 변경하였습니다.모든 폰트는 압축된 woff2 형식으로 제공됩니다.Cal Sans, 0xProtoNerdFontMono, Pretendard 3종이 제공됩니다.백엔드 변경사항에 맞춰 UI 부분도 개선 하였습니다.사용중인 라이브러리들을 본 배포 시점에서 최신 버전으로 모두 업데이트 하였습니다. npm install 실행이 필요합니다![Android - SENSTA]안드로이드 네이티브 앱으로 곧 구글 플레이 스토어에 출시 예정인 SENSTA 는 아래와 같은 특징을 가지고 있습니다.TSBOARD v1.0.5 이상으로 만들어진 사이트와 연동됩니다.TSBOARD에서 만들어진 (갤러리) 게시판 하나를 앱에서 접근합니다. (일종의 커뮤니티 전용 인스타그램인 셈입니다)SENSTA 앱을 여러분이 운영하시는 커뮤니티 사이트에 맞게 일부분 수정이 필요합니다.data/src/main/java/me/data/env/Env.kt 파일을 열어서 아래 코드를 살펴보시고, 수정하시면 됩니다.package me.data.env object Env { const val TITLE = "SENSTA" // 앱 타이틀 const val DOMAIN = "https://sensta.me" // TSBOARD로 개발된 웹사이트 주소 const val BOARD_ID = "photo" // Board ID on TSBOARD const val BOARD_UID = 2 // Board UID on TSBOARD const val CATEGORY_UID = 5 // 기본 카테고리 고유 번호, 게시판 설정에서 카테고리 안쓸 경우 무시됨 const val MAX_UPLOAD_COUNT = 9 // 한 번에 9장까지 업로드 가능 const val MAX_UPLOAD_SIZE = 100L * 1024 * 1024 // 한 번에 최대 100MB까지 업로드 가능 const val VERSION = "v1.0.0" const val MIN_TSBOARD_VER = "≥ v1.0.5" // 이 앱은 운용중인 서버의 TSBOARD가 v1.0.5 이상이어야 동작합니다 const val MIN_ANDROID_VER = "≥ 14" // 안드로이드 14 (Samsung Galaxy S23 시리즈 이후) 이상 버전 필요 const val GITHUB_URL = "https://github.com/sirini/sensta" // 이 앱의 전체 소스코드 GitHub 주소 }SENSTA 앱의 소스코드를 GitHub에서 포크(fork)하신 후, 여러분의 사이트에 맞게 수정하셔서 별도의 전용 앱을 만들어보세요!앱을 제작하신 후에는 직접 구글 플레이 스토어에 심사를 거처 등록을 하셔야 합니다.SENSTA 앱은 안드로이드 네이티브 앱으로, iOS 버전은 현재 없으며 개발에는 Kotlin 언어가 사용되었습니다.추후 TSBOARD가 업데이트 되면서 앱도 계속 개선될 예정이니, 가급적 변경점을 최소화 하시는 걸 권장합니다!TSBOARD가 이미 모바일 기기도 잘 지원하는데 왜 별도의 안드로이드 전용 앱을 만들었는지 궁금하신가요?제 블로그에 뒷얘기가 있습니다 : https://tsboard.dev/blog/sirini/66TSBOARD 기반으로 직접 만들어서 운영중인 sensta.me 사이트 이용자분들을 위해 만들기 시작했습니다.만들다보니, 조금만 고치면 다른 TSBOARD 기반 커뮤니티에서도 유용하게 쓰일 것 같아 코드를 공개하였습니다.TSBOARD는 이제 커뮤니티 사이트를 위한 종합선물세트가 되어가고 있습니다.아직도 많이 알려지진 않았습니다만, 언젠가는 이 글을 보실 여러분들 혹은 다른 개발자분들에게 도움이 되리라 생각합니다. 😊개인적으로는 TypeScript / Go / Kotlin과 같은 쓰기 좋은 언어들과 함께 시간을 보낼 수 있어 기쁩니다. (C++이 없어서 천만다행…?!)마지막으로 TSBOARD v1.0.5 태그 페이지 링크로 마무리 하겠습니다!👉 https://github.com/sirini/tsboard/releases/tag/v1.0.5
cover image

안드로이드 앱 개발의 즐거움

0 0 84

요즘 저는 안드로이드 앱 개발에 빠져 있습니다. TSBOARD로 개발하여 운영중인 저의 첫 커뮤니티, sensta.me 사이트 사용자분들을 위한 안드로이드 전용 앱을 만들고 있는데, 정말 재밌습니다. TSBOARD를 만들면서 접했던 여러 개념들이 비슷하게 등장하는 것도 신기했는데, 타입스크립트와 Go 언어에 이어서 코틀린 언어의 매력에 허우적거리는 제 모습이 낯설기도 하고 신기하기도 합니다. 그 중에서도 안드로이드의 클린 아키텍처는 정말 배울만하다는 생각이 들었습니다.안드로이드 클린 아키텍처안드로이드는 공식 아키텍처로 클린 아키텍처를 소개하고 있습니다. Presentation / Domain / Data 이렇게 크게는 3개로 모듈을 나눠서, 각각의 역할을 분리하는 것이 핵심입니다. 처음에는 별로 크지도 않은 앱을 만드는데 무슨 모듈을 3개씩이나 만들지? 라고 생각하고 그냥 하나의 모듈에서 개발을 했습니다만, sensta.me 앱을 만들면서 그게 아니라는 걸 금방 깨달았습니다. 저에게 있어 모듈을 나누는 가장 큰 이유라고 한다면, 약간 이상할 수 있는데 파일이 많아서라고 답하고 싶습니다. Presentation 모듈이 UI와 ViewModel 부분을 담당하고 있는데, 여기도 Jetpack Compose기반으로 앱을 만들다보면 목적에 따라서 여러 컴포저블 함수들이 생성되고, 대부분은 별도의 파일에 속하게 됩니다. 당연히 파일도 엄청 많아지고 덩달아서 파일들을 패키지로 묶어야 하니 패키지도 많아지게 됩니다. 충분히 하나의 독립된 모듈로 빼둘만 하더라구요.Domain 모듈의 경우 설계상 순수 코틀린 언어로만 작성이 필요합니다. 안드로이드 코드가 있어선 안되고, 원칙적으로는 외부 라이브러리에 의존하지 않습니다. 이곳에서는 리포지토리의 인터페이스들을 정의하고, 모델들을 정의합니다. 그리고 UseCase라고 부르는 것들을 작성하는데, 하나의 UseCase를 보통 하나의 파일에 저장하니까 이 역시도 파일이 많아질 수 밖에 없습니다. 여러 모델들과 리포지토리 인터페이스, 그리고 ViewModel에서 기능 호출할 때 사용하는 UseCase까지 파일이 많아지니까 자연스럽게 이걸 하나의 독립된 모듈로 구성하는 게 낫겠다는 생각이 들더군요.Data 모듈은 실질적으로 데이터 입출력과 관련된 일들을 하는 곳이고, Domain 모듈에서 정의해둔 리포지토리 인터페이스들을 구현하는 곳이니만큼 당연히 파일들이 많아집니다. 특히 저의 경우는 앱 자체가 외부 서버에서 JSON 타입의 데이터를 가져와야 하다보니 JSON 타입과 매칭되는 DTO를 여기서 정의해 두었습니다. DTO가 거의 대부분 모델과 일대일 매칭이 되므로 역시 파일이 많아집니다. 결국 독립된 모듈로 구성하는 것이 정답이었다고 할 수 있습니다.마법같은 Coroutine안드로이드 앱은 사용자에게 보여지는 UI가 있고, 해당 UI에서 특정 버튼이나 행위(예: 스크롤)를 했을 때 그에 맞춰 동작이 일어나야 합니다. 때로는 시간이 소요되기도 하겠죠. 그러나 어떠한 경우에도 사용자의 UI는 멈춰선 안됩니다. 버튼을 터치했을 때 날씨를 가져와서 보여준다고 가정하면, 날씨 데이터는 결국 인터넷 망을 통해서 가져와야하니 시간이 걸리게 됩니다. 가령 5초가 걸렸다고 합시다. 이 때 안드로이드 앱의 화면 여기저기를 터치하거나 했을때 먹통이 되어버린다면 어떨까요? 당연히 해당 앱은 쓸 수 없는 앱이 됩니다.이걸 막기 위해서 코틀린은 코루틴(Coroutine)을 지원하고 있습니다. 이게 참 신기하게도, TSBOARD를 개발하면서 백엔드를 Go언어로 재작성 할 때 이미 고루틴(Goroutine)을 맛본 상태라 다행히 개념이 어렵진 않았습니다. 고루틴이 언어 자체적으로 지원하는 기능이라는 점과 사용이 훨씬 쉽다는 점을 제외하면, 코틀린 언어의 코루틴도 정말 훌륭한 동시성 구현이라고 생각합니다.안드로이드 앱 개발을 할 때는, UI에서 특정 버튼이 터치되었다고 가정해보면, 해당 버튼의 onClick 이벤트 리스너에서는 ViewModel의 특정 함수를 호출하고, 해당 함수는 내부적으로 viewModelScope.launch { … } 블럭을 실행하면서 그 블럭 안에서 UseCase를 호출하도록 보통 구현한다고 합니다. 저도 조금 생소하긴 했었는데, 몇번 하다보니 금새 익숙해 졌습니다. // 개별 알림 확인 처리하기 fun checkNotification(notiUid: Int) { viewModelScope.launch { val user = getUserInfo() if (user.token.isEmpty()) { return@launch } checkNotificationUseCase(user.token, notiUid).collect { if (it is TsboardResponse.Success) { loadNotifications() } } } }viewModelScope.launch 블럭은 코루틴 영역이고, 기존 코드 흐름과는 별도의 영역에서 실행됩니다. 그리고 그 안에서 호출되는 UseCase는 보통 Flow를 반환하는데, collect 함수가 호출되면 그 때 emit 함수로 필요한 데이터를 가져옵니다. 저는 이 과정이 정말 굉장하다고 생각했는데, 일반적으로 Blocking을 하면서 데이터 받는 걸 기다리는 게 아니라, Non Blocking으로 메인 스레드를 막지 않으면서도 데이터를 가져오는 이 흐름이 정말 낯설면서도 한편으로는 익숙하다는 느낌을 받았습니다. TSBOARD를 처음 만들때 Node.js의 비동기 I/O 개념을 배운 게 여기서도 도움이 되더라구요.Node.js의 혁신적이었던 비동기 I/O 동작과 콜백 기반의 처리, 그리고 Promise를 통해서 해소된 콜백 지옥… 이 배움들이 코틀린 언어의 코루틴을 사용하면서도 그대로 적용되었습니다. 코루틴에서도 새로운 코루틴 영역을 만들어주는 async {…} 블럭이 있고, await 함수를 통해서 비동기적으로 동작하는 함수들의 실행 결과를 기다렸다가 받아서 처리할 수도 있었습니다. 타입스크립트와 Node.js 그리고 Bun과 함께했던 시간들이, Go언어와의 시간들이 헛되지 않고 계속해서 새로운 배움의 마중물이 되어준 것입니다.만족스러운 네이티브 앱의 성능안드로이드 앱 개발을 즐겁게 만들어주는 가장 마지막 요소라고 한다면, 단연 네이티브 앱이 보여주는 성능이 아닐까 싶습니다. 물론 Flutter와 같은 크로스 플랫폼 개발 프레임워크가 여러 장점들이 있다는 것을 잘 알고 있습니다. Dart 언어 역시 훌륭하고, 지금 생각해보니 Flutter의 선언형 UI 개념들이 Jetpack Compose에서도 자연스럽게 이어지는 것 같다는 생각이 들었습니다. 그러나, 크로스 플랫폼을 위해 별도의 UI 엔진을 불러와야하고, 코틀린이 아닌 Dart 언어로 개발해야 한다는 점 등이 조금 걸렸습니다. Dart 언어는 물론 훌륭한 언어이고, 한 때 자바스크립트를 대체하기 위해 야심차게 소개된 것도 알지만 현실적으로 Flutter외에는 잘 안쓰이는 언어이다보니 배우고 싶다는 동기부여가 잘 안되었다는 점도 말씀드리고 싶습니다. 초기 로드 외에도 네이티브 앱이 조금이라도 더 빠릿하게 반응하고 더 부드럽게 애니메이션을 해주며 더 빠르게 데이터를 처리하지 않을까 하는 믿음도 있습니다. ㅎㅎ그런 관점에서, React Native는 애초에 고민하지도 않았습니다. 웹 기반 기술은 브라우저가 가장 적합한 플랫폼이라고 생각합니다. TSBOARD의 경우 지금까지 타입스크립트를 계속 사용했었고, 한 때 백엔드에서도 썼던 만큼 안드로이드 앱을 만든다고 하면 가장 좋은 선택지가 React Native입니다. 하지만 지금 다시 생각해보면, 오히려 React Native를 선택하지 않은 덕분에 코틀린 언어에 대해서 알게 되고 기존에 배우고 써왔던 다른 언어와의 공통점들도 발견하게 될 수 있었습니다. 결정적으로 Flutter와 비교했을 때 성능 차이가 확연히 드러났을거라 생각합니다. 딱 한가지 아쉬운 점은, vscode를 사용할 수 없다는 점입니다. 엄밀히 말해서 쓸 수 없는 것 까지는 아니지만, 안드로이드 스튜디오가 압도적으로 개발 생산성이 좋습니다. 딱 이 점만 제외하면, 코틀린 언어와 함께하는 안드로이드 앱 개발은 정말 즐거운 여정입니다. 곧 소개하겠습니다 : Sensta 앱TSBOARD 기반 커뮤니티에서 쉽게 활용 가능한 안드로이드 앱, Sensta 프로젝트는 GitHub에 전체 코드를 공개(https://github.com/sirini/sensta)하고 있습니다. 우선은 sensta.me 사이트 사용자분들을 위해서만 개발되고 있지만, TSBOARD로 운영되는 그 어떤 커뮤니티에서도 쉽게 활용 가능합니다. 1차 목표는 4월 30일까지 구글 플레이에 등록 가능한 수준으로 만들어보는 것인데, 잘 될 수 있도록 응원을 부탁드리겠습니다!
cover image

TSBOARD 기반 커뮤니티에서 쓸 수 있는 안드로이드 앱 개발중!

0 0 128

안녕하세요! TSBOARD 개발하고 있는 시리니입니다.TSBOARD 프로젝트와 연계한 신규 프로젝트를 슬슬 소개해 드리고자 합니다.(졸린 와중에 쓰는 글이라 조금 횡설수설 한 것 같습니다. 양해 부탁드립니다!)제가 이 곳에서도 잠깐 소개해 드렸던 sensta.me 사이트, 혹시 기억하시나요?사진 좋아하는 사람들끼리 서로 사진도 올리고 구경도 할 수 있는 그런 곳이면서, 동시에 TSBOARD의 커뮤니티 기능들을 테스트 해보는 공간입니다.해당 사이트를 개발할 때부터 사실 자체적으로 앱을 만들어서 사용자 분들이 좀 더 편리하게 사진도 공유하고알림 기능을 통해서 서로 메시지도 주고 받으면 좋겠다는 생각을 쭉 했었는데,이번에 TSBOARD가 어느 정도 안정화되면서 미뤘던 앱 개발 프로젝트를 시작하였습니다.(아직 구현된 페이지보다 안된 페이지들이 훨씬 많긴 합니다… ㅎㅎ)대략적인 디자인이나 구성은 위의 이미지들과 같습니다. 아마 의아하실 분들도 계실듯 합니다. React Native나 하다 못해 Flutter 기반으로 개발하는 게 아니라굳이 안드로이드 네이티브 기반으로 개발중인 이유가 뭐냐? 아이폰 용은 어떻게 할거냐?일단 변명 아닌 변명을 하자면, 웹 기반이나 크로스 플랫폼은 기기에 최적화된 성능을 내기 어렵다는 생각이많이 들어서 처음부터 제외했습니다. 물론 아이폰용 앱도 개발을 할 예정인데, 굳이 안드로이드를 먼저 한 건회사에서도 마침 안드로이드 앱 관련 프로젝트 일부를 맡게 되어서이기도 하지요.(그리고 이번 기회에 Kotlin 언어를 배워보려고 합니다)위 프로젝트는 사이트 이름에 맞춰서 SENSTA 라는 이름으로 진행중입니다.삼성 갤럭시 S23 Ultra 기기를 제가 가지고 있어서 그걸 테스트용 삼아서 만들어 나가고 있습니다.근데, 여기까지만 보면 딱히 새로울 거 없는 평범한 안드로이드 앱 아닌가? 하는 생각이 드실 겁니다.SENSTA 앱의 가장 큰 특징은, 아주 쉽게 설정만 변경해도 여러분의 커뮤니티 사이트에 딱맞는 앱을바로 만들 수 있다는 점입니다. object Env { const val title = "SENSTA" const val domain = "https://sensta.me" const val boardId = "photo" }SENSTA 프로젝트에서 Env.kt 파일을 보시면 위와 같이 되어 있습니다. 사이트 이름과 도메인, 그리고 주로 열람할 게시판 ID 하나만 지정하시면 여러분의 커뮤니티 전용 앱이 완성됩니다.(물론 앱 아이콘 변경 같은 약간의 작업 정도는 해주셔야 합니다만 … ㅎㅎ)자체 앱을 제작하려면 SENSTA의 소스 코드를 받을 수 있어야 하겠죠?아래의 경로에서 확인 하실 수 있습니다.https://github.com/sirini/senstaTSBOARD 백엔드와 좀 더 잘 통합되도록 개발해 나가면서, 안드로이드 기기에 최적화된 UI/UX로사이트 이용자분들이 더 편리하게 서비스에 접근하실 수 있도록 해보려고 합니다.언제 구글 플레이에 올릴 수 있을지 정확히는 잘 모르겠지만, 가능하면 올해 상반기 내 출시를 해보겠습니다.sensta.me 사이트에도 많은 관심 부탁드리고, SENSTA 프로젝트에도 많은 응원 부탁드립니다! 😆
cover image

가르치면서 배우기 : 최고의 학습법

0 0 56

최근 안드로이드 앱 개발을 해야 할 일이 생겨서, 이래 저래 코틀린(Kotlin) 언어 세미나를 자청해 배운 내용들을 정리하고 내부에 공유하는 작업을 진행하고 있습니다. 그러면서 자연스레 후배 동료분들에게 어떤 식으로 설명을 하는 게 좋을지, 어떤 개념들을 어떤 순서로 말하고 이해하도록 하는 것이 좋을지 고민하게 되었습니다. 그러다 문득, 깨달은 한가지가 있었습니다. 아 내가 안다고 생각했던 것들이 실제로는 제대로 아는 게 아니었구나, 하는 것을요.변수인데 왜 변경이 안되는 게 있는거지?코틀린 언어는 저에게 있어서도 생소했고, 부서원들에게도 물론 생소한 언어였습니다. 부서원 대부분은 C++만 사용하고 있고, 그마저도 최근에 조인하신 분은 파이썬으로 과제 정도를 진행해 본 것이 전부인 분입니다. 그래도 저의 경우 TSBOARD 프로젝트를 진행 하면서 Go 언어를 배우고 사용할 기회가 있었고, 타입스크립트(자바스크립트) 언어도 사용해서 그런지 문법이나 개념들이 크게 어려워 보이진 않았습니다. 즉 다른 언어를 사용하면서 무의식중에 체득한 지식들 상당수가 코틀린 언어에서도 그대로 적용된 것입니다. 그래서 처음에는 다른 동료분들에게 제가 배운 내용을 설명하는 것이 그렇게 어려울 거라고 생각하지 못했습니다. 제가 이미 아는 개념이 코틀린에서는 어떤지 파악한 다음, 그 내용을 잘 녹여서 설명하면 될거라고 (안이하게) 생각했던 거죠.그러나 이 생각이 얼마나 잘못된 것이었는지 코틀린 언어의 변수 부분을 설명하면서 바로 깨닫게 되었습니다. 그나마 C++를 사용하고 있는 동료분들은 C++이라는 비교 대상이 있어서 공통점과 차이점 중심으로 빠르게 학습할 수 있는데, 파이썬만 접한 상황에서 코틀린의 변수 개념을 접할 때는 다소 이해가 안가는 게 있을 거라고 생각하지 못했습니다. 가령 이름이 변수인데 변경 가능한 변수가 따로 있고 변경 불가능한 것이 따로 있는 게 무슨 의미인가? 와 같은 생각을 제가 해본 적이 없었던 것이었습니다. 그저 의례 하는 것처럼 “대충” 다른 언어에 있는 개념이니까 깊게 생각하지 않았었는데, 이러한 의문에 대해 제가 답을 해야 하는 상황이 오자 답변이 막막했습니다. 스스로 굉장히 부끄러웠습니다.변경 불가능한 변수가 왜 필요한가? 코드를 작성하면서 이후에 잘못된 변경 시도를 방지할 수 있다. 그렇게 했을때 뭐가 좋은가? 의도하지 않은 잘못된 값이 사용 되는 걸 방지할 수 있다. 그 밖에 무슨 장점이 있는가? 컴파일 시점에 이미 값이 변경 안되는 걸 알기에 더 최적화에 용이하다. 또 다른 장점은? 예를 들어 매직 넘버(숫자만 적힌 것)를 의미 있는 이름을 부여해서 사용할 수 있다. 등등…이전까지 알고 있다고 착각했던 것들은 실제로는 아는 게 아니었습니다. 말 그대로 착각인 겁니다. 변수라는 개념은 프로그래밍 언어를 배울 때 가장 먼저 배웁니다. 하지만 그렇다고 해서 이 변수가 가장 쉽고 간단하기 때문에 먼저 배우는 건 아닙니다. 이 개념을 알아야 그 뒤에 이어지는 제어문이나 함수, 클래스와 같은 개념들을 이해할 때 더 쉽기 때문에 가장 먼저 배우는 것일 뿐입니다. 이름이 변수인데 정작 변경이 안되는 변수에 대한 의문을 깨닫게 되면서, 이런 중요한 걸 이제서야 배우다니! 하는 탄식도 들었습니다.문은 뭐고 식은 뭔가요?우리가 통상 제어문을 배울 때 의식하지 않고 “문” 이라고 표현해서 배웁니다. 저도 여지껏 새로운 언어를 배울 때마다 제어문(statement)이라는 단어에 대해서 생소하다는 느낌을 받아본적이 없었습니다. 하지만 이걸 설명하려고 다시 생각을 해보니까, 정확히 이걸 구분해서 생각한 적이 없었다는 생각이 들었습니다.코틀린은 if나 else 혹은 switch를 대신하는 when이 표현식(expression)입니다. 보통 제어문이라고 배우는데, 코틀린은 아닙니다. if 나 else, when 같은 표현식은 마지막 값이 리턴값이 되어서 변수에 넣을 수가 있거든요. 아주 간단히 생각하면 값 처럼 평가가 되는 겁니다.fun main() { val a = 10 val b = 20 // if 표현식 val max = if (a > b) a else b println(&#34;Max: $max&#34;) // 출력: Max: 20 // when 표현식 val grade = 85 val result = when { grade >= 90 -> &#34;A&#34; grade >= 80 -> &#34;B&#34; grade >= 70 -> &#34;C&#34; else -> &#34;F&#34; } println(&#34;Grade: $result&#34;) // 출력: Grade: B }삼항 연산자가 없는 코틀린이 불편하지 않은 이유도 if 가 표현식으로 값으로 평가되기 때문입니다. 그런데 이 개념, C++만 사용한 동료들에게는 정말 생소한 개념이었습니다. if 가 값처럼 취급된다는 소리가 이해가 안되는 것입니다.#include <iostream>using namespace std; int main() { int a = 10, b = 20; // if 문 (표현식이 아님, 변수에 직접 할당 불가) int max; if (a > b) max = a; else max = b; cout << &#34;Max: &#34; << max << endl; // 출력: Max: 20 // switch 문 (값을 반환하지 않음) int grade = 85; string result; switch (grade / 10) { case 10: case 9: result = &#34;A&#34;; break; case 8: result = &#34;B&#34;; break; case 7: result = &#34;C&#34;; break; default: result = &#34;F&#34;; } cout << &#34;Grade: &#34; << result << endl; // 출력: Grade: B }그 때문에 문은 무엇이고 식은 무엇인지에 대해서 다함께 다시 생각해보는 시간을 가지게 되었습니다. 저에게 있어서는 비유를 들자면 C++에서 말하는 lvalue / rvalue를 명시적으로 구분하는 것에 버금가는 배움의 기회였습니다.코루틴(Coroutine)은 스레드(Thread)에요?코루틴에 대한 부분을 설명할 때는 정말 저 스스로가 진짜 많이 모른다고 생각이 들었던게, 그냥 스레드인데 가벼운 스레드다! 라고 설명 하자니 너무 축약된 부분이 많다는 점을 알게 되었습니다. 코루틴은 엄밀히 말하자면 스레드가 실행 환경이 되는 것이고, 그 안에서 돌아가는 중단 가능한 객체들을 코루틴이라고 해야 할텐데 이걸 설명하는 것도 쉽지 않았습니다.그리고 스레드라는 개념도 약간 생소한 상황에서 저런 설명을 들어봤자, 이해가 하나도 안되는 게 사실입니다. 그래서 고민을 하다보니, 아래와 같은 순서로 개념들을 쌓아 나가야 코루틴까지 다다를 수 있겠다는 생각이 들었습니다.동시성(Concurrency)은 무엇이고 병렬성(Parallelism)은 무엇인가?기존의 멀티 스레드(Multi Thread) 방식은 무엇이 문제였나?동기(Synchronous)와 비동기(Asynchronous)의 차이는 뭔가?블록(Block)과 논블록(Non-Block)의 차이는 뭔가?그리고 동기와 비동기와의 관계는?코루틴은 멀티 스레드와 어떻게 다른가?중단 가능한 객체라는 것은 무슨 의미인가?코루틴 빌더는 무엇이고 코루틴 스코프는 또 무엇인가?구조적 동시성이라는 개념은 무엇인가?메인 스레드와 코루틴이 동작하는 스레드의 차이는 무엇인가?그리고 코루틴이 동작할 스레드를 바꿀 수 있다는 의미는 무엇인가?안드로이드에서 쓸 수 있는 코루틴 스코프는 무엇인가? 왜 따로 정의되어 있는가?코루틴이라는 하나의 개념에 이르기까지 생각보다 많은 개념들을 알아야 한다는 걸 알게 되었습니다. 그냥 막연히 이럴 것이다, 혹은 Go 언어의 고루틴과 비슷한거야, 라고 단정짓는 것은 뇌에 일종의 속임수를 쓰는 것이나 다름 없었습니다. 더 깊게 고민하거나 개념들을 애써 정리하게되면 에너지가 소모 되니까, 에너지를 덜 쓰는 방향으로 그동안 스스로를 속였던 셈입니다.이 모든 진실들을, 누군가에게 제가 알고 있는 개념이나 배운 내용에 대해서 설명하려고 할 때 비로소 깨닫게 되었습니다. 하나의 개념을 제대로 이해하기 위해서는 생각보다 더 많은 사전 지식이 필요합니다. 대충 설명하는 건 쉽지만 제대로 설명하는 건 어렵습니다. 때론 아주 단순한 하나의 개념 속에도 미처 생각하지 못한 점들이 많이 있었습니다. 겉으로는 제가 누군가에게 지식을 전달하는 단순한 일이었지만, 실제로는 제가 그동안 안다고 착각했던 지식들을 다시 한 번 점검하고, 이면을 깨닫고, 개념을 더 엄밀하게 파악할 수 있는 소중한 기회였습니다.누군가를 가르친다는 건 실제로는 스스로의 무지를 깨우치는 훌륭한 학습법이라고 생각합니다. 이번 코틀린 언어 학습이 잘 마무리되면 자청해서 다른 프레임워크나 언어에 대한 세미나도 진행해봐야 겠습니다. 😊
cover image

물품 거래 : 최소 기능으로 시작하기

0 0 64

TSBOARD에도 드디어 회원 간의 물품 거래를 보다 편리하게 할 수 있도록 하는 기능이 생겼습니다. 개발에는 생각보다 시간이 제법 걸렸는데, 이번에는 안드로이드 개발 공부도 있긴 했지만 의도적으로 속도를 좀 늦췄습니다. 천천히 개발하면서 과연 어떤 방향이 더 맞을지 생각하는 시간을 많이 가졌고, 덕분에 처음 구상한 기능들을 덜어내면서 최소한의 기능만으로도 훌륭하게 첫 발을 내딛을 수 있었습니다. 몇가지 고민했던 부분들과 제가 정리한 방향에 대해서 기록을 남겨봅니다.물품 거래 후 피드백물품 거래 기능을 개발할 때, 몇가지 레퍼런스를 두고 시작 했습니다. 단연 그중 으뜸은 당근입니다. 저 뿐만 아니라 많은 분들이 사용하고 계시는 국민 앱이 되었는데, 이 당근 앱을 보면 중고 물품을 거래하고 난 이후 서로에 대한 피드백을 남기도록 되어 있습니다. 약속 시간에는 제때 왔는지, 물품의 상태는 게시글에 적힌 것과 같은지 등이며 이런 피드백들이 쌓여서 매너 온도라는 지표가 업데이트 됩니다.처음에는 TSBOARD에서도 이런 피드백 과정을 염두해 두고 개발을 진행했습니다. 아무래도 회원 간의 거래다보니 뭔가 까다로운 피드백 절차 까지는 아니더라도 별점을 매긴다던지 하는 게 필요하다고 생각했었거든요. (매너 온도 비슷한 지표를 생각했습니다) 그러다가 다른 커뮤니티 사이트에서는 중고 물품을 어떤 식으로 거래하고 있는지 살펴보았는데, 의외로 피드백 부분이 없었습니다. 처음에는 다른 커뮤니티 사이트에서 구현하지 않았으니까 TSBOARD에서 하면 의미가 있겠다! 싶었는데, 곰곰히 생각해보니 굳이 그럴 필요가 없어 보였습니다.일단 커뮤니티 사이트는 특정 주제 중심인 경우가 많고, 대부분은 중고나라처럼 무언가를 팔거나 사기 위해서만 이용하지 않습니다. 때문에 물건을 판매하는 쪽에서도 사는 사람이 같은 커뮤니티 이용자라는 점을 인지한 상태로 팔고, 사는 분도 마찬가지여서 완전 생판 모르는 사이끼리 거래는 아니라는 점이 달랐습니다. 또한 커뮤니티 사이트내의 중고 물품 거래는 어차피 댓글 등을 작성하면 모두가 볼 수 있어서 그것이 좋은 피드백이든 살벌한 비판이든 바로 드러나게 됩니다. 따라서 굳이 별점이나 여러 피드백 절차를 추가할 필요가 없다는 결론에 도달하였습니다. 구매자와 판매자간의 소통가장 고민을 많이 했던 부분입니다. 당근의 경우 앱이기 때문에 채팅 기능도 있고, 앱 알림도 바로 오기에 크게 문제가 없지만 TSBOARD는 아직 앱이 없어서 고민이 되었습니다. 그나마 쪽지 기능이 1:1 소통으로 가능하기 때문에 우선적으로는 메시지 보내기 같은 기능으로 대체하고, 추후 TSBOARD 앱이 개발되면 그 때 알림 기능을 반영하는 걸로 타협을 보았습니다.판매자가 자신의 전화번호를 입력하게 해도 되는데, 아무래도 개인정보라서 이걸 보관하게 두는 것이 맞나 하는 생각이 계속 들었습니다. 가능하면 판매자가 오픈카톡방을 만들어서 링크를 전달해주고, 서로 소통 후에 거래 의사가 확실해지면 그 때 판매자의 자의로 전화번호를 메시지 혹은 오픈카톡을 통해서 전달하는 방식을 선택했습니다.찜하기당근의 경우 마음에 드는 물건이 있다면 찜하기로 찜해두고, 언제든지 해당 제품의 가격 변동 상황을 파악하거나 할 수 있습니다. 판매자에게도 이건 좋은 기능인데, 많은 사람들이 찜을 했다는 건 그만큼 관심을 많이 받고 있다는 뜻이므로 판매될 가능성이 높다는 시그널을 받을 수 있습니다. 그래서 저도 이 찜하기 기능을 구현 하면서 동시에 내가 찜한 물품의 가격이 변동되면 TSBOARD 시스템으로부터 쪽지를 받게 한다거나 메일로 알림을 받도록 하려고 했었습니다. 테이블도 간단하게 구성하고 구현을 하려다가, 문득 TSBOARD의 좋아요 기능이 결국 찜하기와 같은 맥락이 아닌가? 하는 생각이 들었습니다. 좋아요 기능은 게시글이 마음에 들면 눌러서 표시하는 건데, 물품 거래 게시판에서 특정 게시글에 좋아요를 눌렀다는 건 결국 찜하기와 동일한 맥락이 아닌가? 하는 생각에 다다른 것입니다. 그래서 불필요하게 찜하기 관련 DB 테이블을 만들거나 하지 않고, 좋아요 기능을 그대로 쓰도록 하되, 추후 좋아요를 누른 사용자에게 선택적으로 가격 변동 등에 알림을 받도록 하는 방향으로 수정하였습니다. (이 기능은 추후 구현 예정)어찌보면 참 간단한 기능인데 생각보다 많은 부분들을 고민했던 것 같습니다. 만약 시간에 쫓겨서 개발을 진행했다면 아마도 불필요한 기능들만 중구난방으로 구현해두고 나중에 가서야 또 제거하는 일을 벌여야 했을 겁니다. 구현보다 설계에 좀 더 시간을 쓰라는 격언을 새삼 떠올려 봅니다.
cover image

TSBOARD v1.0.4 업데이트 안내!

0 0 101

안녕하세요! 아주 오랜만에 TSBOARD 업데이트 소식을 가지고 왔습니다!업데이트 작업을 간간히 하는동안, TSBOARD를 사용하는 커뮤니티 사이트에서 쉽게 활용 하실 수 있는안드로이드 앱을 어떻게 만드는지 공부 하느라 조금 늦어졌습니다. 🥲 (v1.0.4 이후에는 안드로이드 앱 개발이 진행될 예정입니다.)🚨 먼저 v1.0.4 업데이트를 위해서는 아래와 같이 goapi-linux-x64 바이너리를 실행해 주셔야 합니다../goapi-linux-x64 updateupdate 인자를 전달하면 trade 테이블을 새로 추가하는 작업이 진행된 후, 백엔드가 실행됩니다.이번 업데이트는 아래의 변경사항을 포함합니다.물품 거래 게시판이 추가되었습니다.신규 혹은 기존 게시판의 타입을 “거래” 로 설정하시면 반영됩니다. 이곳에서 샘플을 보실 수 있습니다: https://tsboard.dev/trade/market기본 화폐 단위 아이콘은 원화로 설정되어 있습니다. 변경을 원할 경우 tsboard.config.ts CURRENCY 변수에 값을 변경해주세요.첫 페이지 로드 시 페이지가 3번 빠르게 변경되는 버그를 수정하였습니다.기본 폰트가 Pretendard로 변경되었습니다. 로고 폰트도 동일하게 변경되었습니다.YouTube 영상 임베딩이 안되던 문제를 수정하였습니다.게시판의 카테고리 사용 여부 설정이 업데이트 안되던 버그를 수정하였습니다.물품 거래 기능은 커뮤니티 사이트에서 거의 대부분 가지고 있는 기능입니다.일반적인 게시판에 회원들이 글 내용을 양식에 맞춰서 입력하도록 하거나, 혹은 추가적인 기능을 제공해서회원들이 거래 관련 정보를 더 입력할 수 있도록 해주고 있습니다. TSBOARD에서는 중고 물품 거래에 필수적으로 요구되는 아래 정보들을 trade 테이블에서 관리하도록 했습니다.제조사 이름 혹은 브랜드물품 분류가격물품 상태거래 위치거래 방식 (택배 혹은 직거래)거래가 완료되면, 게시글 작성자가 쉽게 거래 상태를 완료로 변경 하실 수 있습니다.한가지 고민은 전화번호를 추가로 보관해야 할까 하는 것인데, 가급적 TSBOARD 쪽지 기능으로 1:1 대화를 통해서구매자와 판매자가 소통을 시작하고, 거기서 필요 시 오픈카톡방 URL 혹은 전화번호를 교환하는 걸로사용 흐름을 잡았습니다. 추후 TSBOARD 안드로이드 앱이 준비되면, 안드로이드 사용자분들은(아마도?) 앱 알림을 통해서 메시지 내용을 바로 받으실 수 있으실 겁니다.v1.0.4를 기다려주신 분들께 감사 드립니다! 사용중에 버그를 발견 하셨다면 언제든지 알려주세요!
cover image

프로젝트를 지속적으로 유지하는 비결 : 늘 미완성으로 두기

0 0 61

꼭 거창한 프로젝트가 아니더라도, 무언가를 만들고 이를 공개 하면서 다른 사람들의 피드백도 받아보고 또 개선하는 활동은 에너지를 필요로 합니다. 생업으로 하는 프로젝트는 월급이나 기타 수익을 기대하는 마음으로 시간을 쏟을 수 있지만, TSBOARD처럼 그냥 기대 이익 없이 하는 프로젝트의 경우 동기 부여가 없다면 지속하기 어렵거든요.사이드 프로젝트를 진행하면서, 생업과 크게 관련없는 작업물을 만들어가는데 시간을 무한정 쓸 수는 없습니다. 개발자도 사람이고, 사람은 기계가 아니기 때문에 전기만 넣어준다고 언제나 풀파워로 작업 할 수는 없거든요. 오히려 계속 작업하는 게 해당 프로젝트를 빨리 끝내버리는 기폭제가 될 수도 있습니다.그렇다면, 생업에 직결된 것도 아니고, 그저 남는 시간에 재미로 혹은 그저 내가 만들어 쓰고 싶어서 진행하는 사이드 프로젝트를 오래도록 유지할 수 있는 비결이 있다면 무엇이 있을까요? 저도 사실 정답을 알고서 쓰는 글은 아니지만, 나름의 생각을 공유해 보려고 합니다.완급 조절하기 : 100m 전력 질주 하지 않기프로젝트를 진행하다보면 어느 시점(예를 들어 v1.0.0)에 이르러 프로젝트의 초기 목표를 달성 했거나, 최소한 기본적인 기능은 나름대로 동작하게 됩니다. 그 때가 오면 당장 새로운 기능을 추가하지 않는 한, 기본적인 버그 수정 등을 거친 후에 프로젝트 개발 속도가 조금씩 감소하게 됩니다. 사실 지금의 TSBOARD 역시 v1.0.3을 지나고 v1.0.4부터는 템포가 조금 느려지고 있습니다. 이런 현상은 자연스럽다고 생각하고, 열심히 TODO 리스트를 지워가던 시기가 있다면 지금처럼 새로운 TODO 리스트를 상상하는 시간도 있어야 한다고 생각합니다.운동도 사이드 프로젝트도 완급 조절이 중요합니다. 처음에 프로젝트를 시작했을 때의 열정과 에너지는 무한히 지속되지 않습니다. 이를 인정하고, 빠르게 달릴 때와 속도를 늦추고 새로운 가능성을 탐구하는 시간이 꼭 필요합니다. 저도 마찬가지지만 우리의 프로젝트가 하루 이틀만에 완성되는 초단기 프로젝트가 아니라면, 호흡을 너무 바삐 가져갈 필요는 없습니다.기대 금지 : 다른 사람은 이 프로젝트에 관심이 없다이건 정말 중요한데, 다른 사람들이 내가 진행하고 있는 프로젝트에 대해서 큰 관심이 없다는 당연한 사실을 받아들여야 합니다. 누가 봐도 내 프로젝트는 정말 중요해! 라고 할 수 있는 건 정말로 드물다고 할 수 있습니다. 정말로 중요했다면, 누군가가 이미 했을 것입니다. 그리고 진짜 많은 관심을 받아야 마땅한 프로젝트라면, 누군가가 이미 알아봐 주었을 것입니다. 개인이든 기업이든 후원을 해주고 이 프로젝트가 진심으로 계속 될 수 있도록 여러분의 시간에 마땅한 투자를 해주었을 겁니다. 그렇지 않다는 것은, 이 프로젝트가 객관적으로 다른 사람들에게까지 중요하거나 관심을 받을 수 있는 건 아니라는 것입니다. 이 점을 받아들여야 합니다.그렇다고 해서 저나 여러분이 하고 있는 사이드 프로젝트가 가치 없다거나 무의미한 것이라는 뜻은 결코 아닙니다. 다른 사람들이 알아봐 주지 않더라도, 적어도 그 프로젝트를 진행하는 여러분들에게 있어서는 큰 가치가 있습니다. 저만 하더라도 TSBOARD 프로젝트를 통해서 현대적인 웹 개발에 대해 배울 수 있었고, 타입스크립트라는 언어를 통해서 풀스택 개발을 해보는 경험을 빠르게 쌓을 수 있었습니다. 지금도 조금 생소한 Bun 런타임을 먼저 써보면서 장단점을 배울 수 있었고, Go 언어에 대해서 배워가면서 백엔드를 더 안정적으로 운영하는 길도 찾아가고 있습니다. 사이드 프로젝트를 통해서 저는 많은 것을 배웠고, 배우고 있습니다. 그리고 저에게 있어 그것 만으로도 이미 충분합니다. 여러분들도 마찬가지일 거라 생각합니다.늘 미완성인 부분을 남겨두기 마지막으로 가장 중요한 비법, 프로젝트를 끊임없이 지속하는 방법은 바로 미완성인 부분을 늘 코드에 남겨두는 것입니다. 예를 들어 // TODO : 추후 구현할 것(개선할 것) 처럼요. 새로운 기능들을 추가할 때 한 번에 작업하려고 하지 말고, 우선 설계만 잡아둔 상황에서 빈 함수들이나 혹은 인터페이스만 선언해 둡니다. 새로운 기능들이 UI 상에서 드러나지 않거나 어딘가로부터 요청되지 않는다면, 해당 코드는 사실상 코드 관점에서는 아무 일도 하지 않습니다. 사실 없어도 그만인 코드니까요.하지만 앞서 계속 언급한 것처럼, 개발자인 우리는 사람이고, 사람은 그렇게 미완성으로 남은 코드 조각들을 편한 마음으로 볼 수가 없습니다. 비어 있는 함수들은 계속 생각이 나고, 언젠가 시간이 좀 나면 이렇게 저렇게 채워둬야지 정도의 생각이 머리 속 한켠에 늘 남아있게 됩니다. 그러다가 문득 시간이 비는 날이면, 아 맞다! 그 // TODO 부분이나 좀 채워둬야지 하고 에디터를 열게 됩니다. 일종의 스스로에게 넛지(옆구리를 슬쩍 찌르기)하는 셈이죠. 이렇게 미완성인 채로 계속 신경 쓰이게 만드는 코드를 남겨두면, 언젠가 그걸 채우게 되고, 또 다시 새로운 미완성 조각들을 남겨두면서 프로젝트가 죽지 않고 계속 살아있게 만들 수 있습니다. 사실 프로젝트에 완성이라는 건 없지만, 좀 더 현실적으로 코드 관점에서도 미완성인 영역이 눈에 보이게 만드는 게 핵심입니다.지속 가능한 사이드 프로젝트를 위하여사이드 프로젝트는 개발자에게 배움의 기회와 무언가를 만들어가는 재미를 선사합니다. 이 배움과 만드는 재미를 오래도록 누리기 위해서는 좀 더 느긋하게 마음 먹고, 다른 사람으로부터의 관심이나 인정에 목매지 않으면서, 늘 미완성인 부분을 코드에 남겨두는 지혜가 필요합니다. (사실 이 글을 쓰면서 스스로에게 하는 조언이라고 생각하며 썼습니다 ㅎㅎ) 우리 신나게 느긋하게 사이드 프로젝트 개발해봐요. 😊
cover image

안드로이드, 코틀린 그리고 TSBOARD

0 0 86

TSBOARD는 v1.0.3을 기점으로 우선은 좀 시간을 두면서 코드 개선이 필요한 부분들이 어디인지 살펴보고 있습니다. 그러는 동안, 저는 다소 뜬금 없지만 안드로이드 앱을 만들어보려고 합니다. 그것도 TSBOARD로 제작된 커뮤니티를 위해서요. (아직은 여기 뿐이지만…?) 저는 갑자기 왜 안드로이드를, 그것도 플러터나 React Native 같은 방식으로가 아닌 코틀린으로 네이티브 개발을 하려는 걸까요? 내 손안의 컴퓨터 세상, 모바일 웹 만으로는 부족해 TSBOARD를 개발할 때 모바일 버전과 PC/태블릿 버전을 함께 고려해서 개발 하기는 했습니다만, 그럼에도 약간 아쉬운 부분들은 존재합니다. 물론, 대부분의 기능들이 무리없이 모바일 브라우저에서 동작하기 때문에 앱 푸시 알림 같은 기능들을 제외한다면 이론적으로 안되는 건 그리 많지 않습니다. 그러나, 브라우저가 아닌 앱이 줄 수 있는 더 다양한 기능들과 더 부드러운 UI, 그리고 앱 아이콘을 찾아서 터치만 하면 바로 접근 가능한 점 등은 앱 개발에 대한 나름의 동기부여를 해줍니다. 유명한 커뮤니티 사이트들을 살펴보면, ① 해당 사이트의 내용을 크롤링해서 더 보기 편하게 해주는 앱이 있거나 ② 아예 자체적으로 앱을 개발해서 배포하는 경우가 종종 있습니다. ①의 경우 해당 사이트가 API를 제공하면 모르겠지만, 대부분은 제공하지 않기 때문에 크롤링이 언제나 가능하지는 않을 수 있고, 또 API가 공개 되어 있더라도 내부 사정에 의해 언젠가 바뀌게 되면 무용지물이 되는 경우도 있습니다. ②의 경우는 당연히 더 나은 상황이지만, 이렇게 자체적으로 지원하려면 커뮤니티 사이트 운영진이 추가로 앱까지 개발하고 유지/보수해야 하는 문제가 있죠. 여하간 이렇게 커뮤니티 사이트들을 살펴보면, 웹 만으로는 부족하다고 느끼는 분들이 많은 건 확실해 보입니다. 저 역시도 브라우저 영역이 예전 대비해서 훨씬 확장되고 더 강력하다는 것은 인정합니다만, 그럼에도 여전히 브라우저의 영역 밖에서 더 강력한 컴퓨팅 파워를 쓰고 싶은 갈망은 계속 있어왔습니다. 그러던 것이 결국 TSBOARD v1.0.0 공개를 기점으로 조금씩 분출되어 앱 개발까지 이어지게 되었습니다. 왜 크로스 플랫폼이 아닌가? 이왕 웹 개발과 조금 떨어져서 개발할거면, 웹 기반의 크로스 플랫폼은 아니길 희망했습니다. (아닐 수도 있지만) 너무 뻔하고, 제가 목표로 하는 더 부드러운 UI에도 그렇게 부합하지 않는다고 생각했기 때문입니다. 물론 구글이 밀고 있는 플러터(Flutter)의 경우 언젠가 데스크탑 애플리케이션을 개발할 날이 오게되면 그 때는 주저없이 선택하겠지만, 모바일에서는 아직까지 네이티브 개발이 퍼포먼스를 끌어내는데 유리하다고 판단했습니다. 이성적으로는 크로스 플랫폼으로 개발을 해야, 한 번에 안드로이드와 아이폰을 공략할 수 있으니 그렇게 하는 게 맞지 않나? 라고 생각했습니다. 그러나 TSBOARD 앱이 나온다면 그건 웹과는 확실히 달라야 한다는 생각이 들었고, 퍼포먼스 측면에서 보다 모바일 기기의 자원을 더 쉽게 끌어다 쓸 수 있기를 희망했기에 그러지 않았습니다. 감성적으로는, 이번 기회에 써보고 싶었던 코틀린(Kotlin)을 제대로 체험해보고 싶다는 생각이 들었습니다. 마침 업무적으로도 이제 써볼 기회가 생겨서 궁금하던 차였기에, 이왕 배우게 될 거 TSBOARD의 안드로이드 앱 개발에도 활용해보자는 생각이 들었습니다. 코틀린은 TSBOARD의 백엔드 언어로 한 때 유력하게 고민했던 언어입니다. 자바와 100% 호환되는 언어이고, 문법 설탕도 어느 정도 달달하게 들어가 있고, 여러 모로 개발자의 생산성에 집중한 언어에 Null Pointer Exception (NPE)을 막기 위한 안전장치까지 마련되어 있는 “요즘 언어” 라고 할 수 있습니다. 백엔드에서는 최종적으로 더 심플하고 제 기준에 딱 부합하는 Go 언어를 선택하면서 코틀린을 써볼 기회가 사라졌지만, 이제 TSBOARD 앱을 개발하게 되면서 다시 코틀린을 만나게 되는 셈입니다. 안드로이드 앱을 먼저 만드는 이유? 쓰는 장비들이 사과 농장에 버금가는 수준이라, 사실 처음에는 iOS용 앱을 개발할까 고민 했었습니다. 겸사 겸사 Swift 언어도 배우면서요. 그러나 업무적으로도 코틀린을 써야 하는 상황에서, 동시에 2개의 언어를 배워가며 이것 저것 하는 건 비효율적이라 생각 했습니다. 더군다나 저의 경우 업무용 스마트폰으로 이미 안드로이드 기기(Galaxy S23 Ultra)를 가지고 다니는데, 여지껏 한 번도 안드로이드 앱을 만들어 본 적이 없다는 사실이 뭔가 부끄럽기도 했습니다. 또한 앞서 언급한대로, 코틀린이라는 언어에 대한 갈증이라고나 할까요? 그런 점들이 분명히 있었기 때문에 고심 끝에 안드로이드용 앱을 먼저 만들어보기로 결정했습니다. 사실 이것 말고도 애플 개발자 등록 비용이랄까 그런 부분도 없잖아 고민을 했었습니다…😊 TSBOARD APP : 2025년의 목표 우선 올해는 TSBOARD를 안정적으로 개발하는 게 제일 큰 목표입니다. v1.0.z 버전대에서는 Go 언어로 작성된 백엔드의 퍼포먼스를 좀 더 높이는 목표를 설정하였고, 이어서 v1.1.0 에서 더 다양한 기능들을 담아낸 다음, v1.2.0 에서 쇼핑몰 기능도 추가해 보려고 합니다. 그러는 한 편, TSBOARD 안드로이드 앱을 개발하면서 TSBOARD의 다양한 기능들을 안드로이드 기기에서 보다 편리하게 사용하고, 푸시 알림 같은 걸 누릴 수 있도록 할 생각입니다. 이렇게 개발한다면 아마도 아래와 같은 게 가능해 질 것입니다. TSBOARD로 제작된 커뮤니티 사이트는 따로 앱 개발이 필요 없어집니다. TSBOARD APP을 설치해서 해당 사이트를 등록하기만 하면 되니까요. 운영자분도 별도 앱 개발 없이 커뮤니티 회원분들에게 앱 설치 가이드만 제공하시면 됩니다.TSBOARD로 운영되는 커뮤니티 사이트는 보다 컨텐츠에만 집중하실 수 있습니다. 사이트 유지/보수를 위한 여러 골치아픈 작업들부터 앱까지 개발에 관여하실 필요가 없습니다. 그 시간에 더 알찬 컨텐츠 생산과 관리에 시간을 쏟으실 수 있습니다.TSBOARD 기반 커뮤니티를 이용하시는 회원 분들은 기존 사이트 이용 및 앱을 통한 푸시 알림도 원할하게 받으실 수 있습니다. 또한 앱 기반에서 동작 가능한 여러 부가 기능들 (키워드 푸시 알림 등)이 가능해 질 것입니다. 아직은 이렇게 할 수 있지 않을까…? 막연히 생각만 해보면서 이제서야 안드로이드 스튜디오를 설치하고 코틀린을 배워나가는 상황입니다만, 목표만 흔들리지 않는다면 더 많은 분들에게 실질적으로 유용한 플랫폼이자 앱이 될 것이라 믿습니다. 그렇게 되도록 작년 한 해 열심히 달려온 TSBOARD를 더 좋은 성능과 더 다양한 기능들로 무장시키고, 또 앱도 천천히 하지만 즐겁게 만들어 가보려고 합니다. TSBOARD 안드로이드 앱은 아래 링크에서 코드를 보실 수 있습니다. 아직은 미약하지만, 올해가 가기 전에는 어느 정도 성과가 나와 주기를 기대해 봅니다…! https://github.com/sirini/sensta