가장 먼저 이 글은 의식의 흐름 그대로 적을 예정이기에 어떠한 질서도 없을 예정이다. 글의 제목은 다른 직종보다 디지털에 가까운 내가 요즘 느끼는 감정이다. 내가 원래 되고 싶었던 인간상이기도 하다. 디지털에 둘러싸여 있어도 그 속에서 아날로그의 무언가를 첨가할 수 있는 그런 사람. 그나마 유명한 사람이라고 하면 로스트아크 금강선 디렉터를 아주 좋은 예로 들 수 있겠다. 게임을 개발하는 사람이라지만 그 사이에서 사람들을 매료시킬 수 있는 언변, 글솜씨 등이 정말 존경스럽다. 보통 사람들은 아주 치밀하게 손익을 계산하며 지내고 있었지만 낭비없는 낭만은 없다고 말할 수 있는 사람. 어떤 것이 불편한지 공감할 수 있는 사람. 진짜 공감을 통해 사람들을 진정시킬 줄 아는 사람. 게임 내 특정 기능이 불편할 때 ..
나는 이번 시리즈를 책의 순서대로 소개해보려 한다. 책의 모든 내용을 소개하진 않을 것이고 내 마음에 남았던 부분만을 적어볼 예정이다. 먼저, 이 책은 신기하게도 내가 가장 관심있어하던 부분을 위한 빌드업부터 시작한다. 정말 놀라웠던 문장은 내가 어느 유튜브에서 보고 깊게 공감했던 내용이었는데 아래와 같다. 코딩도 결국 글쓰기와 같다. 솔직히 말하면 어떤 다른 문장도 이 문장을 이길 수 없을 것이다. 모든 문장을 대변하는 한 줄이다. 이 다음은 글쓰기 기본에 대해 소개하고 있는데, 글의 독자가 누구인지, 그에 따라 문장이 어떻게 구성되어야 하는지 생각해야 한다. 특히 개조식 글에는 글머리 기호를 써야한다. 다들 아는 네모나 동그라미 등이 예시일 것이다. 같은 챕터에서 글쓰기와 코드를 작성할 때 어떤 원칙..
정말 오랜만에 프로그래머스에 접속해보았다. 머리가 많이 굳었다는 게 실감되었다. 아날로그에 빠져 살아서 그랬나 싶기도 하다. 이제 문제풀러 가보자. 문제 일단, 두 수가 연산자를 거치면 문자열마냥 합쳐지는 것을 볼 수 있다. 따라서, 두 Int형 파라미터를 문자열로 붙였다. 만들어진 문자열을 다시 숫자로 바꾸어 a*b*2의 결과와 비교했다. 풀이 실행 결과
내가 이 클래스를 사용하게 된 이유 내가 사용하던 RecyclerView에는 각 아이템 하단에 구분선(Divider)이 있다. 이전에는 해당 아이템을 구성하는 xml에 MaterialDivider를 배치했었다. 새로운 요구사항이 들어오면서 구조 변경의 필요성을 느끼게 되었다. 새로운 요구사항은 마지막 아이템은 구분선이 가로 전체를 차지하도록 변경하는 것이었다. 새로운 요구사항에 따른 시도 RecyclerView Adapter의 onBindViewHolder에서 마지막 아이템을 확인해서 AttributeSet을 다시 할당해주었다. 나름 그럴싸한 로직이라 생각했다.(내 기준) 그 결과, 알 수 없는 버그들이 밀려들어왔다. 처음 adapter를 할당했을 땐 마지막 아이템에만 해당 AttributSet이 적용되..
Step 1. Create the SleepNight entity 이번 과제에서는 하룻밤 수면을 데이터베이스 엔티티를 의미하는 annotated data class로 정의한다. 하룻밤의 수면을 위해서는 시작 시간, 종료 시간, 퀄리티 등급을 기록해야 한다. 그리고 하룻밤을 구분하기 위해 고유 아이디가 필요하다. 1. database 패키지의 SleepNight.kt 파일을 연다. 2. SleepNight 데이터 클래스를 id, 시작 시간(millisecond 단위), 종료 시간(millisecond 단위), 숫자의 수면 퀄리티 등급 파라미터를 사용해 만든다. 품질 데이터가 수집되지 않았다는 것을 나타내기 위해 sleepQuality를 -1로 초기화해야 한다. 시작 시간을 유효한 시간으로 초기화한다. 선택..
안드로이드에서 데이터는 데이터 클래스로 표현된다. 이 데이터는 함수 호출에 의해 접근되고 수정될 수도 있다. 그러나, 데이터베이스 세계에서는 데이터에 접근하고 수정하기 위해서는 entity와 query가 필요하다. 엔티티는 속성과 함께 데이터베이스에 저장할 객체나 개념을 의미한다. 우리의 앱 코드에서 테이블을 정의하는 entity class가 필요하다. 해당 클래스의 각 인스턴스는 해당 테이블의 행을 의미한다. Entity class는 데이터베이스의 정보를 표시하고 상호 작용하는 방법을 Room에 알려주는 맵핑이 있다. 우리 앱에서 엔티티는 하룻밤 수면에 관한 정보를 가지고 있을 것이다. 쿼리는 테이블(혹은 테이블 조합)의 정보 또는 데이터 요청이거나 데이터에 대한 작업을 수행하기 위한 요청이다. 일반적..
저번 Notification 글에 이어 이번 글은 알림 최대 갯수에 관한 포스팅이다. 글을 시작하기 앞서, 여러 자료를 통해 확인한 부분도 있고 내가 수동으로 테스트를 통해 직접 확인한 부분도 있다. 물론 확인되지 않은 부분도 있다. (이런 부분은 계속 짚고 넘어갈 예정이다.) 알림 최대 갯수라고 해서 헷갈릴 수 있는데 앱마다(?) 백그라운드에서 알림이 누적되는 최대치가 있다. (사실 앱마다인건지 해당 알림의 channelId마다인 지는 정확하지 않다) 아무튼 알림이 누적되는 양이 제한되는데 갤럭시 플래그십 라인업은 24개가 대부분이다. (OS 10 이상) 회사에서 Pixel폰으로 테스트해보았을 때는 50개였다. (스택오버플로우에서 찾은 구글 소스 코드 원본도 50개가 최대치이다.) 특정 폰에서는 10개..
최근 나와 부장님을 동시에 이마를 짚게 하는 문제가 생겨서 포스팅해본다. 다른 회사와 나름 '협업'이라는 것을 하면서 메일이나 카톡을 주고 받는 일이 생기곤 한다. 이번 사건(?)은 외부 업체의 기가 막힌 글쓰기로 인해 비롯되었다. 발단 외부 업체에서 개발한 앱이 우리 회사에서 개발한 앱을 딥링크로 호출하는 상태이다. (이제 외부 업체를 A사라고 칭하겠다) 아이디/ 비밀번호 찾기 버튼 클릭 시, A사에 API 요청을 통해 링크를 받아와 해당 링크를 웹뷰로 보여준다. (여기서 이해가 되지 않는 부분은 이미 프로덕션 트랙으로 릴리즈가 되었는데 해당 링크가 유효하지 않아 웹뷰는 에러를 보여주고 있다.) 부장님과 A사의 카톡방에서 A사가 아이디/ 비밀번호 찾기 링크가 변경되었다고 공지했다. 그리고 A사가 보낸 ..
상용 앱들을 보면 어떤 푸시 알림이 왔을 때 해당 푸시가 누적되는 경우가 다반사이다. 하지만, 나는 해당 기능에 대해 구현할 생각을 해본 적이 없었다. 이 때, 갑자기 회사에서 '푸시가 1개밖에 안 쌓여요. 푸시가 누적되게 해주세요.' 라는 요청을 받았다. 기존 코드 notificationManager.notify(0, notificationBuilderCompat.build()) 이 상황에서는 무조건 0번 id로만 notify하기 때문에 새로운 푸시 내용이 도착해도 기존 푸시가 갱신된다. 해결한 코드 notificationManager.notify((System.currentTimeMillis() / 500).toInt(), notificationBuilderCompat.build()) 이렇게 코드를 ..
이번에는 아주 어이없는 실수를 해버린 에피소드를 하나 소개해보려한다. 다른 앱에서 딥링크를 통해 내 앱을 실행하는데 앱이 비정상 종료되는 문제였다. 소위 말하는 앱 크래시현상이다. 이유가 뭐였을까? 먼저 내 앱은 딥링크로 앱 실행 시 스플래시 화면으로 진입하게 되고, 여기서 intent의 data안에 있는 uri를 파싱해 토큰을 얻어온 다음, Extra와 함께 로그인 화면으로 넘어간다. 여기서 갑자기 런타임 에러가 났다는 건데... 나의 경우에는 총 2가지 문제가 있었다. 조건문에서 null처리가 되지 않은 문제(온전한 나의 문제) 딥링크가 정상값이 아님(서버 측 문제) 나의 문제였던 1번의 경우, 앱 푸시를 눌렀을 때 진입점이 같은 스플래시 화면이었다. 여기서 딥링크로 앱을 실행할 때와 차이점이 발생..