LOAS(로스트아크스테이츠)
1620 서포터가 만든 로아 정보 검색 애플리케이션. 나의 최애 캐릭터를 메인화면에 등록하고 간편한 관심 캐릭터 설정까지. 초월장비, 엘릭서, 스킬 등 최신 로아 이벤트와 공지사항들을 간편하게 한번의 터치로 확인 ! - 메인 캐릭터 & 관심 캐릭터 내가 지정한 캐릭터를 메인에 등록 할 수 있고 물론 변경도 가능해요. 캐릭터 상세 화면에서 간편하게 관심 캐릭터로 등록 할 수 있습니다. 최근 검색한 캐릭터 기록을 지우고 싶다면 간단히 밀어서 삭제 ! 당연히 로아를 즐기지 않는분도 모든 컨텐츠를 이용 할 수 있습니다. - 언제 어디서든 한손으로 확인하는 캐릭터 상세정보 기본 능력치와 성향, 장비의 품질, 세트효과, 엘릭서효과, 초월단계까지. 각인과 장착카드, 카드효과 그리고 아바타 정보. 이 모든걸 한손으로 스크롤해서 확인 할 수 있습니다. - 최신 이벤트와 로아의 점검 그리고 공지 메인화면에서 로아의 최신 이벤트 페이지에 바로접속! 별도의 점검 섹션으로 점검일정만 모아서 볼 수 있습니다. - 프로키온의 나침반 업데이트 ! 이제 한 주 동안의 로웬, 모험섬, 필드보스, 항해협동 등 다양한 스케줄들을 놓치지 마세요 !
안녕하세요. 저는 LOAS 개발자 신결 이라고 합니다.
현재 서울 소프트웨어 아카데미 (SeSAC) 영등포 iOS 3기에서 iOS 과정을 수강하고 있습니다.
평소에 SmileGate RPG 사의 ‘Lost Ark’ 라는 게임을 즐겨 하는데 아무래도 게임을 좋아하다보니
이번 출시 프로젝트로 게임의 OPEN API 를 이용해 캐릭터 정보 검색 애플리케이션을 개발하게 되었습니다.
이번 프로젝트는 솔로 프로젝트로 기획과 디자인 등 전반적으로 자기 주도아래에 실행되었습니다.
# LOAS 는?
Lost Ark States 라는 의미로 로스트아크 유저 개개인의 행정구역을 의미합니다.
실제로 인게임에서 ‘영지’ 라는 개인 공간을 가지고 있는데 그것처럼 LOAS 를 이용하는 유저들 하나 하나가 캐릭터 정보를 손 안에서
확인 할수 있는 구역에 네이밍 포커스를 맞췄습니다.
# 무엇을 위한 애플리케이션인가?
LOAS 의 목적 유저들에게 하여금 자신 또는 타인이 육성하고 있는 캐릭터의 레벨, 아이템, 채용 스킬, 수집 컬렉션, 보유 캐릭터와 같이
전반적인 정보를 ‘간편하게’ 확인하고 특히 타인의 정보를 확인 할 때는 그 캐릭터들을 벤치마킹 하면서 게임에 대한 동기를 부여합니다.
또, RPG 게임의 특성 중 하나인 사람간의 추억을 만들 요소를 제공하기도 하면서 멋진 캐릭터의 외형을 꾸미는 유료 아이템 등을 표현해
구매 심리를 어느정도 유발 할 수 있는 전반적인 게임에 대한 충성도와 직접적인 연관이 있습니다.
# 출시하고 무슨일이 일어났는가 ?
생각보다 주변에 로스트아크 유저가 많았습니다.
그리고 1.0 출시 소식을 아시는분들은 다운 받아주셨고 개선할점과 긍정적인 피드백을 주셨습니다.
피드백은
“OPEN API 를 사용한 애플리캐이션 이지만 LOAS 로 인하여 각자의 검색 공간을 가지게 된 느낌을 받았다는 내용”과,
“즐겨찾기 기능으로 그들의 지인의 캐릭터를 등록하면서 서로 이야기 할 거리가 생겨서 좋았다” 라고 주셨습니다.
제가 의도한 바 와 같이 정보에 대한 전달력이 좋았다 라는 내용이 많았습니다.
아직 인게임과 게임 커뮤니티에 홍보를 하고 있지 않은 단계라 다운로드 수는 출시 30일 차에 약 100건에에 불과하지만
그 중 약 82% 가 검색 노출로 발생했다는점에서 약간은 고무적이라 생각하고,
이번 부산에서 열린 G-STAR 2023 의 파급력으로 인해 행사 첫날 애플 앱스토어 연관 검색노출 수 1300 건으로 생각보다 많은 노출이 있었습니다.
이로인해 애플리캐이션 개발을 대하는 적극적인 태도에 조금 더 다가갈 수 있게 되었고
제가 좋아하는 게임의 성장에 간접적으로 기여 할 수 있게 된 것 같아 행복했습니다.
출시 프로젝트를 달성해야 한다는 목적에서 벗어나 기존에 존재하는 다른 정보 검색 서비스들의 불편했던 점을 개선한
‘직관적인’ UI 를 가진 애플리케이션을 만들고싶은게 가장 큰 프레임이었고,
API 에서 배포하는 정보 안에서 어떻게 그 정보를 ‘전달력’ 있게 표현 할 수 있을까 라는 스스로의 욕구에서 출발한것이 LOAS 를 제작하게 된 계기였습니다.
무엇보다, 제가 로스트아크를 좋아하지 않았다면 트리거가 당겨지지 않았을지도 모릅니다.
제가 로스트아크를 정말 좋아하기에 가능했던 일이었습니다.
LOAS 는 1인 솔로 개발로 이루어진 프로젝트입니다만 UX에 대해 지인 디자이너 하늘 님께서 어드바이스를 주셨습니다.
# 기획
작성된 기획안이 있었습니다. 사실상 10개가 넘는 엔드포인트에서 제공하는 매우 방대한 양의 정보를 정리하는게 거의 대부분 이었습니다.
피그마도 잘 다룰 줄 몰랐기 때문에 레퍼런스들과 인게임에서 얻은 스크린샷을 짜깁기해서 레이아웃도 잡아봤으나 결과물하고는 정반대의 기획이었습니다.
추가로 API의 응답값이 어떤 형식으로 오는지, 그것들을 파싱하기 위한 단계들을 고려해야 했고 단순히 API 에서 String 으로 주니까
.text 에 할당할 문제에서 벗어난것들이 많았습니다.
기획 단계에서부터 개발에 대한 난이도가 어느정도 보였으나 현실은 API 자체의 설계 의도를 파악하고
그에 맞춰 액션해야 하는 솔루션이 필요했다 라는것이 기획의 큰 프레임으로 작용한것 같습니다.
#예외처리
제가 정의한 애플리캐이션의 컨셉은 자칭 ‘S2(S Two)’ 로 명명하고 그에 따른 규칙을 정했습니다.
Simple & Straight + 유저가 원하는 정보를 획득하기 위해 2회의 탭 제스처를 초과하지 않는다는것 입니다.
예를들어 장착중인 특정 아이템의 정보를 확인 하기 위해 버티컬 스크롤을 통해 도달했는데
그 포인트에서 또 탭을 해야하고 다시 원래의 정보로 복귀하려면 또다시 탭을 해야 하는 ‘누군가에게 불편한 경험’ 으로부터 자유롭게 설계했습니다.
이런 자체적인 룰을 설정하기 위해 여러 애플리케이션과 레퍼런스 사이트들을 참고 했고 최대한 단점을 보완하였습니다.
이런 규칙은 개발 단계에서 ‘난이도’ 로서 다가오는 결과로 이어지게 됩니다.
# UI & UX
UIUX 에 대한 전공적인 배경이 없음에도 불구하고 제 솔로 프로젝트에서 오히려 유익하고 신선한 도전이었습니다.
다른 애플리캐이션들을 면밀히 분석하고, 유저의 시선에서 장점들을 흡수하려는 노력은 비전문적이기에
한편 어느정도 신선한 접근 방식을 가능하게 했던 것 같습니다.
API 에서 제공해주는 정보와 제가 게임 유저로서 알고싶은 내용들을 ‘남김없이’ 화면에 디스플레이 하기 위해 노력한 부분이 존재했고
캐릭터의 외형과 아이템의 아이콘이 API 에서 제공되기에,
그런 리소스들을 충분히 활용하여 심플한 디자인 속에서도 시각적인 요소가 충족되는 효과를 노렸습니다.
캐릭터의 외형, 현재 진행중인 이벤트의 배너, 공지사항과 같이 API 에서 제공되는 리소스들은 그 자체로 시각적인 요소로 사용하기 매우 적합했습니다.
가장 중요한건 캐릭터의 ‘아이템’ 정보를 표시하는것이었고 UI 에서 이 부분이 가장 많은 시간을 소비하기에 충분했습니다.
Collection View 를 사용하는데 최초에는 Compositional Layout 과 Diffable DataSource 를 적용했었습니다.
그러나 당시 Diffable Datasoure 를 사용하는데 다소 지식이 부족해 Compositional Layout 만 도입하고
그마저도 약간의 추가학습이 필요했기에 흔히말해 ‘삽질’ 과 UI가 마음에 안드는 이유로 변경 및 수정이라는 이벤트가 여러번 일어났습니다.
그리고 UICollectionView Datasource 로 노선을 변경하게 되었습니다.
진행하면서도 ‘그냥 빨리 구현하고 수정하지 왜 지금 이 단계에서 진도를 못나가느냐’ 라는 질문에 둘러쌓여
빈 연습장에 레이아웃 모델과 구조체 모델을 효과적으로 적용하기 위해 많은 아이데이션을 꺼내게 되었고
그 과정 중 하나만 소개하자면 동일한 화면속에 두개의 컬렉션뷰가 같은 스크롤 방향을 가지는 대참사도 있었습니다.
이는 애플 휴먼인터페이스 가이드라인의 권장사항이기도 합니다만 알면서도 왜 그렇게 했는지.. 참회의 반나절이라는 기억으로 남았습니다.
결국 위 스크린샷과 같은 임시 레이아웃이 만들어졌고, 만들고나서 잠깐 생각에 잠기기를.. 이게 대체 뭐라고.. 라는 생각도 해봤습니다.
# Networking
SeSAC 커리큘럼을 통해 배운 Router 패턴을 활용하여, 네트워크 모델을 효과적으로 추상화하는 전략을 채택했습니다.
이 방식은 새로운 기능과 엔드포인트가 추가될 때마다 단순히 Router에 적용하는 것만으로도 유지보수의 편리함을 크게 향상시켰습니다.
또한, 'Alamofire'라는 HTTP 네트워킹 라이브러리를 사용하면서 모든 엔드포인트에 대해 하나의 통합된 네트워크 모델을 제네릭 타입으로 구현함으로써
효율성과 확장성을 동시에 달성할 수 있었습니다.
API의 지속적인 업데이트에 신속하게 대응하는 것은 LOAS 유저들에게 원활한 경험을 제공하기 위한 필수 요소였습니다.
이러한 프로세스를 통해, 단순히 이것이 좋다, 저것이 좋다는 식의 아키텍처 패턴을 넘어서 특정 패턴을 사용해야 하는 근본적인 이유와
그 타당성에 대해 심도 있는 검토를 할 수 있었습니다.
# Modeling
API 데이터의 정확한 파싱은 이 프로젝트의 핵심 과제였습니다.
단순한 'Quick Type' 적용이나 '옵셔널 처리'와 같은 기본적인 해결책들은 실제 문제의 복잡성을 충분히 다루지 못했습니다.
캐릭터별, 계정별 게임 컨텐츠의 달성 여부에 따라 응답값의 부재, 아이템 미장착 캐릭터에 대한 null 응답 처리, 예외 상황에 대한 적절한 대응은 단순한 조건부 로직을 넘어섰습니다.
API가 제공하는 데이터는 광범위하고 상세했지만, 실제로 저의 핵심 가치에 해당하는 데이터는 복잡하게 인코딩된 문자열로 응답되었고 이는 가독성 문제를 일으켰습니다.
또한, 캐릭터의 스펙에 따라 응답 구조가 다양하게 변화하는 점은 파싱 과정을 더욱 복잡하게 만들었습니다.
이러한 문제를 해결하기 위해, 저는 각기 다른 구조를 가진 응답들을 효율적으로 처리할 수 있는 Dynamic Structure를 개발했는데 데이터셋의 규모가 크지 않은 현 상황에서
효과적인 솔루션이었습니다.
이 구조체는 성능 문제 없이 유연하게 다양한 응답 유형을 처리할 수 있었으며 캐싱되지 않은 이미지 로드 외에는 성능 문제를 일으키지 않았습니다.
결과적으로 Dynamic Structure 를 통해 유동적인 구조체들에 대해 일일히 예외처리를 하지 않고도
Response 내에 존재하는 구조체들의 순서, 존재유무를 막론하고 전부 파싱할 수 있게 되었고
게임 자체가 업데이트 되어 추가 구조가 발견이 된다고 해도 매우 빠르게 대응 가능할 수 있는 유지보수 가능성까지 획득 할 수 있었습니다.
제가 원하는 기능인 게임 내에 ‘엘릭서’, ‘초월’ 이라는 컨텐츠를 장비 디테일부분에서 확인하지 않고도 한눈에 알 수 있도록 디스플레이 할 수 있게 되었습니다.
추가적으로 ‘에스더’ 라는 등급의 무기를 보유한 캐릭터의 경우 ‘장갑’ 의 세트 옵션을 그대로 무기에서 가져가는데
‘EstherChecker’ 라는 변수와 메서드로 ‘에스더’ 등급임을 체크하고, true 일 경우 ‘장갑’ 의 세트 옵션을 표현하도록 하였습니다.
#DataBase
Realm을 활용하여 효율적인 데이터 관리를 위한 체계적인 Realm Repository를 구축했습니다.
이를 통해 유저가 즐겨찾기에 추가한 캐릭터의 관리(추가, 삭제, 수정)는 물론, 메인 캐릭터 설정 같은 중요한 기능들을 선제적으로 통합했습니다.
특히, 미설정 캐릭터의 존재를 실시간으로 감지하고, 데이터베이스 상의 정보를 기반으로 유저에게 상황에 맞는
유저 인터페이스를 제공하는 예외 처리 메커니즘을 구현함으로써, 유저 경험을 극대화하였습니다.
더욱이, 데이터베이스 스키마의 업데이트 가능성을 고려하여, 미래 지향적이고 확장 가능한 스키마 설계에 중점을 두었습니다.
이는 잠재적인 마이그레이션 필요성을 최소화하고, 향후 업데이트 시나리오에 유연하게 대응할 수 있는 기반을 마련하였습니다.
#예외처리
매주 수요일 오전 6시 - 오전 10시 사이에 게임의 모든 웹, 온라인 서비스가 정기점검으로 인해 중단되고, API 서버도 같이 메인테넌스에 들어갑니다.
그동안 당연히 리퀘스트를 받지 못하게 되고 앱에 진입하게 되면 서버가 현재 Online 인지 확인하고 만약 점검으로 인해
500번대 에러가 들어온다면 에러코드와 함께 유저에게 Alert 형식으로 점검중임을 보여줍니다.
그 외 API 에서 열거된 에러코드들에 대해 전부 대응하고 있으며 현재까지 계속 자체적으로 QA 를 진행하고 있는데 400번대 에러는 경험해보지 못했습니다.
이렇게 서버사이드나 클라이언트 사이드의 에러를 적절히 처리함으로써 유저 경험에 긍정적인 영향을 주고
시스템의 현재 상태에 대해 명확하게 인지할 수 있게 함과 동시에 혼란을 최소화 합니다.
특히 500번대의 서버 오류와 같이 유저가 해결할 수 없는 문제들이 발생했을 때, 유저에게 상황을 알려주고 기대할 수 있는 서비스 재개 시간을 제공함으로써
유저의 불편을 최소화 하였습니다
#Update Checker 구현
다른 서비스도 마찬가지이고 LOAS를 이용하는데 있어서 저에게도, 유저들에게도 애플리캐이션의 최신화는 매우 중요합니다.
단순히 기능을 추가하는것을 넘어서 공수 기간 내에 100% 구현하지 못했거나 미흡한 부분들을 개선한 사항을
‘먼저’ 유저들에게 다가가는것은 개발만큼 중요하다고 여기기에 Update Checker 기능을 구현했습니다.
구글링하여 제 애플리캐이션에 접목시키려 했습니다만 2 - 30개의 블로그와 문서들을 확인하면서 약간의 하드쉽이 있었습니다.
코드 내용 중 Data(contents: of) 는 Synchronous , 동기적으로 동작하는 메서드인데 Apple 앱스토어의 애플리캐이션정보 JSON 을 받아오면서 Data(contents:of)
메서드를 비동기 처리 하지 않는 포스팅이 대부분이었습니다.
다들 블로그에 올리는 포스팅 내용이 직접 사용해보고 올리시는건지 모르겠습니다.
많은 포스팅에서 동기메서드를 동기로 처리하길래 제가 모르는 부분이 있는지 의심하고 앱에 적용해보니 역시 사용중 메인스레드에서 Blocking 이 일어났습니다.
결국 코드들을 URLSession으로 재구성하여 업데이트 기능을 정상적으로 구현 할 수 있게 되었습니다.
# HTTP Caching Behavior x Update Checker
먼저 LOAS 는 Firebase 의 Remote Config 가 도입 되어있지 않습니다.
LOAS 가 1.2.2 버전에서 마이너 업데이트로 인해 1.3.0 으로 앱스토어에 업데이트 되었을 때 일입니다.
앱스토어에는 1.3.0 이 배포되고 있고 분명 업데이트 기능을 테스트 할 때 까지만 해도 Update Checker 기능은 정상적으로 동작했는데
인앱에서는 계속해서 최신버전이라고 응답하고 있었습니다.
Insomnia 로 리퀘스트를 보냈을때 앱스토어 버전에 대한 JSON 응답은 1.3.0,
Xcode 로 리퀘스트를 보냈을때 1.2.2 여기서, HTTP 캐싱에 대한 문제를 잊고 있었다는걸 직감했습니다.
앱스토어에서 각국 마켓으로 업데이트 되는 과정에서 일어나는 전파지연문제와는 별개로 URLSession 에서 일어나는 NSURL Request 에 대한 캐싱을 확인해볼 필요가 있었습니다.
NSURL 의 Default 는 useProtocolCachePolicy 로 서버 캐시규약을 따르는데 캐시가 만료되지 않은 시점에서 HTTP 통신이 일어나면
이전 캐시를 로드하는 현상이 발생했고 제 앱은 계속해서 앱스토어가 1.2.2 인줄 알게 되었던 것이었습니다.
따라서 Cache 정책을 .reloadIgnoringLocalCacheData 로 변경하여 기존 캐시를 무시하고 최신의 JSON 을 체크하도록 정책을 변경하여 문제를 해결했습니다.
생각보다 LOAS 를 만들면서 어려움의 연속이었지만 전반적으로 제가 좋아하는 테마속에서 개발하게되어 개발 과정이 재미있었습니다.
저는 랭커까지는 아니어도 현재 1620 레벨을 달성하고 있는데 그럭저럭 높은 편에 속합니다. 게임에 대한 이해가 잘 되어있었기 때문에 적절한 구색으로,
그리고 유저들이 캐릭터 정보를 확인 할때 ‘우선적으로 알고싶은’ 컨텐츠가 무엇인지 잘 알고 있었습니다.
이런것을 이렇게 보여주면 어떨까? 이것을 이렇게 보여주고싶은데 잘 안되네, 다른방법은 없을까? 이런 머리아프면서고 즐거운 상상속에 한달을 보냈습니다.
정말 밤낮없이 하루 최대 20시간가량 코딩했어도 5시간 자고일어나서 다음날 또 컴퓨터앞에 앉는 스스로에게서 웃음포인트를 찾기도 했습니다.
대외적으로는 API Developer Team 측과 API 의 제공형식에 대해서 질의 메일을 주고 받아 API 가 개선되는 이벤트도 발생했고 그런것들이 LOAS 를 개발하면서
발생한 저에게 있어서 정말 환상적이고 짜릿한 모먼트였던 것 같습니다.
프로젝트 과정에서 예정된 공수에 맞추어 개발하지 못한 점은 상당한 도전이었습니다.
UI 기획이 충분하지 않았던 점과, 아이템 하나에 대해 긴 Tooltip 문자열이 포함된 Response를 파싱하거나 정규식을 이용하여 문자열을 추출하고
Attribute String을 적용하는 과정에서 발생한 문제들이 시간 관리에 어려움을 가져왔습니다.
그러나, 이러한 과정은 단순한 시간적 문제를 넘어서, 제 개발 과정에서의 열정과 욕심이 더 많은 정보와 다른 앱에서 구현되지 않은 요소들을 표현하고자 하는 동기로 변화했습니다.
이러한 열정은 결과적으로 애플리케이션의 목적 달성과 품질 향상에 긍정적인 영향을 미쳤습니다.
솔로 프로젝트의 자유로움이 시간 관리에 제약을 가져왔지만, 그만큼 얻은 경험과 성취는 더 큰 가치가 있었습니다.
LOAS 의 업데이트 시나리오는 앞으로 계속 남아있고 추가할것입니다.
현재 1.3.2 버전입니다만 다음 마이너 업데이트는 ‘경매장’ 업데이트가 될것 같고 그 이전에 Rate Limit 관련하여 디벨로퍼팀과 상의가 필요하겠습니다.
경매장 업데이트 이후 인게임 영지채널, 항해채널, 로아인벤 등 애플리케이션을 홍보 할 계획에 있습니다.
DAU 를 늘려보고 싶고, 설치했다가 불필요하다고 느껴서 유저가 삭제하더라도 사용하시는동안 지하철에서,
누워서 로아 스트리머들을 보면서, 화장실에서 언제 어디서나 이용 할 수 있는 그런 LOAS 로 만들고 싶습니다.
신결