- 개인 iOS 레이더 앱 Aviator 2.0은 12월 초부터 이어진 OpenSky Network 장애 이후 다시 동작하게 되면서, 실제 사용 중 드러난 불편을 한꺼번에 손본 업데이트임
- 새 컨트롤 메뉴는 점진적 공개 구조로 주요 조작과 고급 도구를 나누고, SwiftUI modal detent와 배경 상호작용으로 레이더 화면을 덜 가리게 구성됨
- 너무 먼 항공기까지 잡히던 문제는 이진 줌 토글로 줄였고, MapKit camera distance를 70km 또는 100km로 바꾸는 방식으로 구현됨
- OpenSky Network API의
origin_country, 고도,category데이터를 활용해 국기 표시, 흐린 날 저고도 필터, 헬리콥터·위성·기체 크기별 아이콘 구분이 추가됨 - 사용자는 OpenSky Network 로그인 정보로 HTTP Basic 인증을 사용할 수 있지만, 2.0에서는 비밀번호가 User Defaults에 저장되므로 민감한 비밀번호 재사용은 피해야 함
Aviator 2.0 업데이트 배경
- Aviator — Radar on your Phone은 아이와 함께 비행기를 찾기 위해 만든 iOS 레이더 앱임
- 이전 글 이후 새 릴리스와 수익화 기회를 생각할 수도 있었지만, 앱은 12월 초부터 OpenSky Network 장애로 사용자에게 오류를 내고 있었음
- 앱을 다시 열었을 때 계속 보이던 502 오류 대신 비행기 감지 알림음이 들리면서 정상 동작을 확인함
- 이후 두 번의 저녁 동안 기존 아이디어를 반영해 Aviator 2.0 작업을 진행함
레이더를 덜 가리는 새 컨트롤 UI
- 2.0에서는 컨트롤을 별도 메뉴로 옮겨 중요한 조작은 앞에 두고, 덜 자주 쓰는 고급 도구는 아래쪽에 배치함
- 이 구조는 점진적 공개(progressive disclosure) 를 사용함
- 메뉴는 SwiftUI modal로 구현되며 두 가지
presentationDetents를 가짐primary: 화면 높이의0.15extended: 화면 높이의0.4
- 드래그 표시기로 메뉴 확장이 가능하다는 점을 보여주고,
presentationBackgroundInteraction(.enabled)로 메인 레이더 UI가 그림자에 덮이지 않게 함 presentationBackground에는 Paul Hudson의 emboss effect를 적용해 실제 레이더 제어판 같은 금속 질감을 더함- 2.1에서는 TipKit을 활용해 어린 Apple 사용자도 점진적 공개 구조를 알아차릴 수 있게 할 계획임
줌 레벨과 레이더 범위 조정
- 1.0에서는 레이더가 너무 잘 동작해, 지평선 너머나 지형 뒤에 있어 볼 수 없는 항공기까지 잡는 문제가 있었음
- 런던 교외처럼 계단식 지형과 섬처럼 이어진 환경에서는 이 점이 실제 사용상 불편해짐
- 개방된 공간에서는 멀리 있는 비행기도 볼 수 있었기 때문에 단순한 감도 문제로만 보기 어려웠음
- 해결책은 줌 기능을 넣는 것이었음
- MapKit SDK의
camera에distance를 미터 단위로 전달해 지표면 확대·축소를 구현함zoomed가 true이면70 * 1_000- false이면
100 * 1_000
- 주말 릴리스에 맞춰 빠르게 구현하면서, 확대된 UI를 강조하기 위해 레이더 원 하나를 제거함
- 처음에는
Slider로 줌 레벨을 처리하려 했지만 A17 칩에서도 충분한 프레임레이트가 나오지 않아, 현재는 이진 줌 토글을 사용함
OpenSky Network 데이터로 추가된 기능
-
국기 표시
- OpenSky Network API는 항공기 트랜스폰더에서 다양한 정보를 수집하지만, 1.0에서는 이 데이터를 충분히 활용하지 않았음
- 2.0에서는 각 비행기 아이콘 아래에 출발 국가를 이모지 국기로 표시하는 토글이 추가됨
- 구현은
origin_country값을 기반으로 함 - API가 제공하는 출발 국가 텍스트 문자열을 받음
- 온라인에서 찾은 국가명 목록으로 2글자 국가 코드로 변환함
- 국가 코드를 유니코드 스칼라로 바꿔 국기 이모지를 구성함
- 사용자가 기능을 켜면 MapKit annotation의 텍스트로
flight.flag를 표시함
-
흐린 날 모드
- 영국의 흐린 날에는 앱에 표시되는 비행기 중 상당수가 구름에 가려 실제로 보이지 않았음
- 높은 항공기를 숨기는 버튼을 추가해, 맑은 모드와 비 오는 모드를 전환할 수 있게 함
- OpenSky Network에서 받은 고도 데이터를 사용하며, 낮은 구름의 기준 바닥값으로 2.5km를 사용함
geo_altitude < 2500.0이면isLowAltitude가 true가 됨cloudy설정이 켜져 있으면 저고도 항공기만 MapKit annotation에 표시함
항공기 아이콘 개선
- 공원에서 테스트하던 중 머리 위로 헬리콥터가 지나갔지만, Aviator는 이를 일반 비행기 아이콘으로 표시함
- OpenSky Network API는 쿼리 파라미터를 추가하면 트랜스폰더가 속한 항공기 종류를 나타내는
category속성을 제공함 - 이 범주에는 다음 같은 항목이 포함될 수 있음
- 15,500파운드 미만의 경량 항공기
- 300,000파운드 초과의 중량 항공기
- 헬리콥터 같은 회전익기
- 우주/대기권 통과 차량
- 낙하산 또는 스카이다이버
- 최신 업데이트에서는 항공기 크기 등급을 구분하고, 위성과 헬리콥터를 별도 아이콘으로 표시함
AircraftCategoryenum에서 이미지, 이모지, 스케일 값을 분리함rotorcraft는xmark.circle.fillSFSymbol을 사용함spaceTransatmospheric은 🛰️ 이모지를 사용함small,large,heavy는 각각0.6,1,1.5스케일을 적용함
- 헬리콥터 이모지는 단색 평면으로 변환했을 때 지나치게 둥글어 보여, 더 추상적인 원 안의 십자 SFSymbol을 선택함
- 이모지를 이미지처럼 다루기 위해
Text를 스케일링한 뒤Rectangle의 마스크로 사용하고, 색상과 CRT 화면 효과를 적용함
사용자 OpenSky Network 로그인
- 사용자가 직접 OpenSky Network 자격 증명을 입력하는 기능이 추가됨
- 이 기능은 Android 버전 다음으로 요청이 많았던 기능 중 하나였으며, 인증되지 않은 API 사용의 rate limiting을 피하려는 목적이 있음
- 전체 컨트롤 메뉴에서 계정을 입력할 수 있고, 등록 페이지로 가는 링크도 제공함
- SwiftUI의
TextField와SecureField로 구현됨@AppStorage("username")@AppStorage("password")
- 2.0에서는 빠르게 프로덕션에 넣는 과정에서 비밀번호를 User Defaults에 저장함
- 다음 릴리스에서는 Keychain에 저장할 예정이며, 현재는 민감한 비밀번호를 재사용하지 말아야 함
- 입력된 사용자명과 비밀번호는 Base64로 인코딩되어 API 요청의
Authorization헤더에Basic인증으로 붙음
마무리
- Aviator 2.0은 아이와 함께 놀 수 있는 앱을 계속 개선하는 업데이트임
- 기능 아이디어나 ASO 팁을 댓글로 요청하며, Aviator — Radar on your Phone 2.0 다운로드와 리뷰를 요청함