iOS 26 AlarmKit으로 알람 앱을 만들며 내린 결정들
iOS 26에서 애플이 공개한 시스템 알람 API인 AlarmKit 위에 알람 앱을 올리면서 실제로 마주친 선택들을 정리했습니다. iOS 18 이하를 왜 포기했는지, 권한 두 개가 각각 무엇을 사는지, 그리고 AlarmKit이 아직 못 하는 일은 무엇인지 프로덕션 관점에서 다룹니다.
📋 핵심 내용 요약
- AlarmKit: iOS 26에서 애플이 공개한 시스템 알람 API. 서드파티 앱도 시계 앱과 같은 경로로 알람을 울릴 수 있게 됐습니다.
- 그 이전: 서드파티 알람 앱의 발사 경로는 알림 하나뿐이었고, 무음 스위치가 켜져 있으면 소리를 낼 방법이 없었습니다.
- 결정 1: iOS 18 이하를 지원하지 않기로 했습니다. 울리지 못할 수도 있는 알람을 파는 것보다 낫다고 봤습니다.
- 결정 2: 권한이 거부되면 알림 경로로 내려가되, 그 사실을 목록에 표시합니다. 차이를 숨기지 않는 쪽을 택했습니다.
- 한계: AlarmKit은 아직 watchOS를 지원하지 않고, 첫 알람음은 iOS가 재생하므로 페이드인을 걸 수 없습니다.
🤖 AI 요약
iOS 26 이전까지 서드파티 알람 앱은 구조적인 한계를 안고 있었습니다. 알람을 울릴 수 있는 경로가 로컬 알림 하나뿐이었고, 알림은 무음 스위치의 영향을 받기 때문에 사용자가 무음으로 자면 소리를 낼 방법이 없었습니다. 앱 스토어의 알람 앱 리뷰에 “안 울렸다”는 불만이 반복해서 올라오는 이유가 여기에 있습니다.
iOS 26에서 애플이 공개한 AlarmKit은 이 구조를 바꿨습니다. 서드파티 앱도 시스템 알람을 예약할 수 있게 되면서, 권한을 허용하면 애플 시계 앱과 동일한 경로로 알람이 발사됩니다. 무음 스위치와 집중 모드를 관통하고, 잠금화면에 풀스크린으로 표시됩니다.
이 글은 AlarmKit 위에 알람 앱을 올리면서 실제로 내린 결정들을 다룹니다. API 사용법 튜토리얼이 아니라, 어떤 트레이드오프가 있었고 왜 그렇게 골랐는지에 대한 기록입니다. 하위 버전을 통째로 버린 판단, 권한 조합별로 동작이 달라지는 문제를 사용자에게 어떻게 알릴지, 그리고 AlarmKit이 아직 해결해 주지 않는 영역이 주요 내용입니다.
AlarmKit이 바꾼 것
AlarmKit은 iOS 26에서 애플이 공개한 시스템 알람 API입니다. 핵심은 간단합니다. 서드파티 앱에게 두 번째 발사 경로가 생겼다는 것입니다.
그 전까지 알람 앱이 쓸 수 있는 수단은 로컬 알림뿐이었습니다. 알림은 잘 동작하지만 알람으로 쓰기에는 결정적인 약점이 있습니다. 무음 스위치가 켜져 있으면 소리를 낼 방법이 없습니다. 알람 앱을 쓰는 사람 중 상당수가 무음으로 자고, 그중 일부는 앱이 알아서 뚫어주리라 기대합니다. 그럴 방법이 없었습니다.
AlarmKit 권한을 허용하면 알람이 애플 시계 앱과 같은 경로로 울립니다. 무음 스위치와 집중 모드를 관통하고, 잠금화면에 풀스크린으로 뜹니다. 시계 앱이 하던 일을 서드파티도 할 수 있게 된 셈입니다.
결정 1: iOS 18 이하를 지원하지 않는다
가장 크고 가장 논쟁적인 결정이었습니다. 배포 타깃을 iOS 26으로 올린다는 건 잠재 사용자의 상당수를 그냥 버린다는 뜻입니다. 신생 앱에게 쉬운 선택이 아닙니다.
그래도 그렇게 한 이유는 이렇습니다. iOS 18 이하에는 AlarmKit이 없으니 발사 경로가 알림 하나뿐이고, 무음 스위치가 켜져 있으면 그 알림은 소리를 낼 수단이 없습니다. 즉 하위 버전에서는 “울릴 수도 있고 아닐 수도 있는 알람”만 팔 수 있습니다.
알람 앱에서 이건 기능 하나가 빠지는 문제가 아닙니다. 제품이 존재하는 이유 자체가 흔들립니다. 사용자는 중요한 아침에 이 앱을 믿고 자는데, 그 신뢰가 조건부라면 앱을 설치하지 않는 편이 낫습니다.
대신 이미 하위 버전에 설치한 사용자는 App Store 정책에 따라 마지막 호환 버전을 계속 사용할 수 있습니다. 기존 사용자를 버리지 않으면서 신규 배포만 iOS 26으로 올리는 방식입니다.
부수 효과도 있었습니다. 하위 버전 분기가 사라지니 코드에서 “이 경로에서는 이렇게, 저 경로에서는 저렇게” 하는 조건문이 통째로 없어졌습니다. 알람처럼 실패가 곧바로 사용자 피해로 이어지는 도메인에서 분기가 줄어드는 건 그 자체로 이득입니다.
결정 2: 권한 두 개, 각각이 사는 것
앱은 권한을 두 개 요청합니다. 각각이 무엇을 사는지 명확히 구분해 둘 필요가 있었습니다.
시스템 알람 (AlarmKit)
허용하면 알람이 애플 시계 앱과 같은 경로로 울립니다. 무음 스위치와 집중 모드를 관통하고 잠금화면에 풀스크린으로 표시됩니다. 알람 앱에서 사람들이 실제로 기대하는 동작이 이것입니다.
알림 (UserNotifications)
허용하면 설정 › 집중 모드의 허용 앱 목록에 앱을 추가할 수 있습니다. 그리고 시스템 알람 권한이 꺼져 있을 때의 대체 발사 경로가 됩니다.
조합별 동작
여기가 설계상 까다로운 지점이었습니다. 두 권한의 조합에 따라 결과가 달라집니다.
| 허용한 권한 | 발사 방식 | 무음 스위치 켬 |
|---|---|---|
| 시스템 알람 (AlarmKit) | 시계 앱과 같은 경로, 잠금화면 풀스크린 | 울림 |
| 알림만 | 일반 알림으로 전달 | 소리 안 남 |
| 둘 다 거부 | 울릴 수 없음 | — |
둘 중 하나만 허용해도 알람은 울립니다. 다만 시스템 알람 권한을 거부하면 알람이 알림으로 전달되므로, 무음 스위치가 켜져 있으면 소리가 나지 않습니다.
둘 다 거부하면 알람이 울릴 수 없습니다. 이 경우 앱은 저장하기 전에 알려주되, 저장 자체를 막지는 않습니다. 사용자가 나중에 권한을 켤 수도 있고, 저장을 막아버리면 그 알람을 다시 만들어야 하기 때문입니다.
결정 3: 차이를 숨기지 않는다
권한이 거부돼 알림 경로로 내려간 알람은 목록에 그 사실을 표시합니다. 조용히 다르게 동작하게 두지 않았습니다.
이건 UI를 지저분하게 만드는 결정입니다. 아무 표시가 없는 쪽이 화면은 깔끔합니다. 그래도 표시하기로 한 이유는, 알람이 안 울렸을 때 사용자가 그 사실을 아침이 아니라 전날 밤에 알아야 하기 때문입니다.
알람 앱에서 가장 나쁜 실패는 조용한 실패입니다. 사용자는 알람을 맞췄다고 믿고 자는데 앱은 소리를 낼 수 없는 상태였고, 그 사실은 늦잠을 잔 뒤에야 드러납니다. 목록에 한 줄 표시하는 비용이 그것보다 훨씬 쌉니다.
AlarmKit이 아직 못 하는 것
watchOS 미지원
AlarmKit은 아직 watchOS를 지원하지 않습니다. iPhone 알람이 시스템 규칙에 따라 손목으로 미러링되고 Watch 스마트 스택에 Live Activity가 표시되기는 하지만, Watch 단독 알람은 만들 수 없고 미션은 iPhone에서 끝내야 합니다.
로드맵에 “Apple Watch 지원”을 적어두고 싶은 유혹이 있는 항목입니다. 하지만 이건 엔지니어링으로 뚫리는 벽이 아니라 OS 차원의 제약이라, 애플이 watchOS용 AlarmKit을 내놓기 전까지는 약속할 수 없습니다.
첫 알람음은 iOS가 재생한다
부드럽게 깨우는 페이드인 기능을 넣으면서 알게 된 제약입니다. 시스템 알람의 첫 소리는 iOS가 재생하기 때문에 앱이 페이드를 걸 수 없습니다. 앱이 제어할 수 있는 건 그 이후 구간입니다.
작아 보이지만 기능 설명을 정직하게 쓰게 만드는 제약입니다. “부드럽게 깨웁니다”라고만 적으면 첫 소리에서 기대가 깨집니다.
시스템 알람 경로는 앱이 소유하지 않는다
이건 제약이라기보다 사고방식의 전환입니다. AlarmKit을 쓴다는 건 발사 시점의 통제권을 상당 부분 OS에 넘긴다는 뜻입니다. 그 대가로 신뢰성을 얻습니다. 앱이 하는 일은 그 위에 미션과 기록을 얹는 것이지, 알람 자체를 다시 구현하는 게 아닙니다.
원칙: iOS 설정을 우회하지 않는다
응답이 없을 때 소리를 키우는 울림 에스컬레이션 기능이 있습니다. 이 기능이 건드리는 것은 앱 자신의 오디오뿐이며, iOS 설정을 우회하지 않습니다.
이건 의도적인 선을 그은 것입니다. 알람 앱을 만들다 보면 “어떻게든 울리게 만드는” 편법에 손이 갑니다. 그 길은 심사에서 막히거나, 막히지 않더라도 사용자가 자기 기기를 통제하지 못하게 만듭니다. 무음과 집중 모드를 관통하는 동작은 편법이 아니라 사용자가 허용한 권한에서 나오는 것이어야 합니다.
같은 원칙이 앱 삭제 방지 기능에도 적용됩니다. 스크린 타임을 이용해 알람이 울리는 동안 삭제 옵션이 보이지 않게 하지만, 이건 잠결의 손가락에 대한 한 겹의 방어일 뿐 절대적인 차단이 아닙니다. 스크린 타임은 언제든 끌 수 있습니다. 그렇게 문서에도 적어두었습니다.
그래도 알람은 보조 수단이다
AlarmKit을 쓰면 알람이 울리지 못하는 상황을 줄일 수 있습니다. 없앨 수는 없습니다.
전원이 꺼진 기기, 방전된 배터리, 거부된 권한, OS가 거는 제약. 어떤 알람 앱도 이런 물리적 실패를 막지 못합니다. 그래서 정말 중요한 아침에는 시계 앱에도 백업 알람을 맞추라고 안내합니다.
자사 앱을 쓰는 사람에게 경쟁 기능을 권하는 셈이라 이상하게 들릴 수 있습니다. 하지만 알람 앱이 파는 것은 기능이 아니라 신뢰이고, 신뢰는 한계를 먼저 말할 때 생깁니다. 늦잠을 잔 사용자에게 “저희 앱은 최선을 다했습니다”라고 말하는 것보다, 애초에 백업을 권해두는 편이 낫습니다.
마무리
AlarmKit은 서드파티 알람 앱에게 오랫동안 없던 것을 줬습니다. 알람이 실제로 울릴 것이라고 말할 수 있는 근거입니다.
대신 새로운 종류의 정직함을 요구합니다. 권한 조합에 따라 동작이 달라지고, watchOS는 아직이고, 첫 소리는 OS가 재생합니다. 이런 것들을 문서와 UI에 그대로 적는 일이 API를 붙이는 일만큼 중요했습니다.
iOS 26에서 알람이나 타이머 성격의 앱을 만드신다면, API 자체보다 권한 조합별 동작을 어떻게 설명할 것인가를 먼저 설계하시길 권합니다. 코드보다 그쪽이 오래 걸렸습니다.
이 글에서 다룬 결정들은 AlarmK라는 iPhone 미션 알람 앱을 만들면서 나온 것입니다. 권한별 동작을 정리한 문서는 AlarmKit 페이지에 따로 두었습니다.