앱 확장은 모바일 앱의 기능을 기본 인터페이스 너머로 확장하는 별도의 실행 모듈입니다: 홈 화면의 Today Widget, CallKit을 통한 VoIP 통화 처리, BroadcastReceiver를 통한 시스템 이벤트 대응. 시스템 통합을 통해 앱은 운영 체제와 깊은 수준에서 상호 작용하여 일반 화면에서 사용할 수 없는 기능을 잠금 해제합니다. Apple 개발자 문서에 따르면, 각 확장은 격리된 프로세스에서 실행되며 기본 앱과 독립적으로 시스템에 의해 관리됩니다. 모바일 앱의 앱 확장을 통해 기본 프로세스에서 사용할 수 없는 기능을 구현할 수 있습니다.
주요 포인트
iOS의 앱 확장은 iOS 8에서 등장하여 모바일 개발에서 시스템 통합의 기초가 되었습니다. 이들은 기본 앱과 함께 번들로 제공되지만 격리된 프로세스에서 실행되는 별도의 바이너리입니다. 각 확장에는 자체 Info.plist와 NSExtensionPrincipalClass를 통해 정의된 진입점이 있습니다. 시스템이 앱 확장의 수명 주기를 관리합니다 — 작업 완료 후 백그라운드에 남아 있을 수 없습니다.
WidgetKit(iOS 14+)은 홈 화면에 위젯을 생성하기 위한 최신 프레임워크입니다. WidgetKit은 인터페이스 설명에 SwiftUI를, 업데이트 일정 정의에 TimelineProvider를 사용합니다. 위젯은 세 가지 크기로 제공됩니다: 소형(2×2셀), 중형(4×2), 대형(4×4). UICollectionViewController 기반의 이전 Today Widget은 계속 지원되지만 Apple은 WidgetKit으로 마이그레이션을 권장합니다. WidgetKit의 앱 확장은 애니메이션, 키보드 입력 또는 제스처를 지원하지 않습니다 — 주기적으로 업데이트되는 정적 또는 의사 애니메이션 요소입니다.
Share Extension을 사용하면 시스템 공유 시트를 통해 모든 앱에서 사용자의 앱으로 콘텐츠를 보낼 수 있습니다. Share Extension은 NSExtensionItem을 통해 데이터를 수신하고 UI에 SLComposeServiceViewController를 사용합니다. Action Extension은 제자리에서 콘텐츠를 처리합니다 — 예를 들어, 다른 앱으로 전환하지 않고 브라우저에서 텍스트를 번역합니다. 두 유형 모두 제한된 시간 내에 작업을 완료해야 하며, 그렇지 않으면 시스템이 확장을 "종료"합니다. 이것은 모바일 앱에서 앱 확장의 중요한 제한 사항입니다 — 백그라운드 작업은 확장 수준에서 사용할 수 없습니다.
iOS의 시스템 통합은 위젯을 훨씬 넘어섭니다: CallKit, PushKit 및 SiriKit을 통해 모바일 앱이 시스템 수준에서 작동할 수 있습니다. 이러한 프레임워크는 특수 entitlements가 필요하지만 사용자에게 원활한 경험을 제공합니다 — CallKit을 통한 통화는 일반 전화 통화처럼 보이며, Siri는 앱을 열지 않고 요청을 처리합니다.
CallKit은 잠긴 화면을 포함하여 타사 앱 통화를 시스템 통화 화면에 통합합니다. CXProvider가 앱을 VoIP 서비스로 등록하고 CXCallController가 통화를 관리합니다. CallKit은 중복 통화를 자동으로 차단하고 원치 않는 번호를 차단하는 Call Directory Extension을 지원합니다. CallKit을 사용한 모바일 개발의 시스템 통합은 음성 통신 앱에 중요합니다 — WhatsApp, Skype 및 Zoom이 수신 통화 표시에 사용합니다.
PushKit은 사용자에게 표시하지 않고 모바일 앱에 직접 푸시 알림을 전달합니다. PushKit은 "종료된" 상태에서 앱을 깨우고 PKPushRegistryDelegate를 통해 데이터를 전달합니다. 이것은 VoIP 앱의 주요 메커니즘입니다: PushKit이 통화 정보를 전달하고 CallKit이 표시합니다. PushKit은 일반 푸시 알림보다 높은 전달 우선순위를 가지며 배너 표시가 필요하지 않습니다. 모바일 앱의 앱 확장은 음성 통신을 위해 PushKit과 CallKit을 자주 결합합니다.
SiriKit을 사용하면 Siri 및 단축어 앱을 통해 요청을 처리할 수 있습니다. Intents Extension은 지원되는 인텐트를 등록하고 처리하는 별도의 앱 확장입니다. SiriKit은 20개 이상의 도메인을 지원합니다: 통화, 메시지, 결제, 메모, 운동. 단축어를 통해 사용자는 자동화를 만들 수 있습니다 — 예: "Siri를 통해 WhatsApp에서 메시지 보내기." SiriKit 및 단축어와의 시스템 통합은 사용자가 앱을 열지 않고 작업을 수행하므로 참여도를 높입니다.
BroadcastReceiver는 시스템 브로드캐스트 메시지에 반응하는 Android 구성 요소입니다. iOS 앱 확장과 달리 BroadcastReceiver는 별도의 바이너리가 필요하지 않습니다 — 매니페스트에서 또는 Context.registerReceiver를 통해 코드에서 수신기를 등록하면 됩니다. Android의 시스템 통합은 종종 BroadcastReceiver에서 시작됩니다: 장치 부팅 시 서비스 시작부터 네트워크 연결에 반응하는 것까지.
IntentFilter는 BroadcastReceiver를 특정 시스템 이벤트에 바인딩합니다. 일반적인 이벤트: BOOT_COMPLETED(장치 부팅), CONNECTIVITY_ACTION(네트워크 변경), BATTERY_LOW(배터리 부족), TIME_SET(시간 변경). 수신기는 AndroidManifest.xml에서 또는 동적 등록을 위해 Context.registerReceiver를 통해 등록됩니다. 동적 등록이 바람직합니다 — 매니페스트 권한이 필요하지 않으며 앱이 활성화된 동안에만 작동합니다. Android에는 앱 확장이라는 개념이 없지만 BroadcastReceiver가 유사한 역할을 수행합니다 — 시스템 통합을 통해 앱 기능을 확장합니다.
NotificationListenerService는 모든 시스템 알림을 수신하는 서비스입니다. NotificationListenerService에는 BIND_NOTIFICATION_LISTENER_SERVICE 권한과 접근성 설정을 통한 액세스가 필요합니다. AccessibilityService는 시스템 통합을 위한 더 강력한 도구입니다: 화면 콘텐츠를 읽고, 클릭을 시뮬레이션하고, 작업을 자동화할 수 있습니다. 두 서비스 모두 설정에서 사용자가 명시적으로 활성화해야 하며, 이는 보안을 향상시킵니다. AccessibilityService를 통한 모바일 앱의 시스템 통합은 자동 채우기, 화면 읽기 프로그램 및 접근성 도구에 사용됩니다.
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
WorkManager.getInstance(context)
.enqueueUniqueWork("post-boot", ...)
}
}
}
이 예제는 BOOT_COMPLETED 이벤트에 대한 BroadcastReceiver를 등록합니다. WorkManager는 장치 부팅 후 지연된 작업 실행에 사용됩니다 — Android 앱의 표준 접근 방식입니다.
Android의 App Widget Provider는 위젯 컨텍스트에서 iOS 앱 확장의 대응물입니다: 홈 화면에 대화형 콘텐츠를 표시하는 구성 요소입니다. WidgetKit과 달리 Android 위젯은 사용자 입력(클릭, 토글, 제스처)을 받을 수 있습니다. App Widget Provider는 크기 및 업데이트 빈도의 XML 설명을 통해 매니페스트에 등록됩니다.
RemoteViews는 XML 레이아웃을 통해 위젯 인터페이스를 설명하고 제한된 View 세트만 지원합니다. RemoteViews는 사용자 정의 View를 허용하지 않습니다 — TextView, ImageView, Button, ProgressBar와 같은 표준 구성 요소만 가능합니다. AppWidgetProvider는 위젯 업데이트, 활성화 및 삭제를 처리하는 기본 클래스입니다. onUpdate 메서드는 updatePeriodMillis를 통한 타이머 또는 정밀한 제어를 위한 WorkManager를 통해 호출됩니다. Android에서 위젯과의 시스템 통합은 주의가 필요합니다 — 너무 빈번한 업데이트는 배터리를 소모합니다.
Glance API는 XML 대신 Kotlin DSL을 사용하여 위젯을 생성하기 위한 Jetpack 라이브러리입니다. Glance API는 RemoteViews로 컴파일되며 Compose와 유사한 구문을 지원합니다: GlanceComposable, Column, Row, Text. 이 라이브러리는 복잡한 XML 코드의 문제를 해결하고 JUnit을 통한 위젯 테스트를 가능하게 합니다. Glance API는 아직 모든 RemoteViews 기능을 지원하지 않습니다 — 복잡한 대화형 위젯의 경우 클래식 접근 방식이 더 좋습니다. Android의 모바일 개발에서 앱 확장은 Glance API 쪽으로 진화하여 위젯 생성 및 유지 관리를 간소화하고 있습니다.
Content Provider는 통합된 ContentResolver 인터페이스를 통해 앱 간에 구조화된 데이터를 공유하기 위한 Android 구성 요소입니다. iOS 앱 확장과 달리 Content Provider는 별도의 프로세스를 생성하지 않습니다 — 데이터는 호출 앱의 컨텍스트 내에서 동기적으로 요청됩니다. Content Provider는 Android 시스템 통합의 기초입니다: 연락처, 미디어 파일, 캘린더 및 표준 앱이 데이터 게시에 사용합니다.
FileProvider는 앱 간 안전한 파일 전송을 위한 ContentProvider의 하위 클래스입니다. FileProvider는 Android 7+에서 금지된 직접 file:// 경로 대신 임시 content:// URI를 생성합니다. 사용하려면 XML 구성에서 files-path 또는 external-files-path를 지정해야 합니다. Android의 모바일 개발에서 앱 확장은 별도의 개념으로 존재하지 않지만 FileProvider가 그 기능을 수행합니다 — 단일 앱을 넘어 데이터 공유 기능을 확장합니다.
iOS에서 파일 공유의 역할은 File Provider Extension이 수행합니다. File Provider Extension은 NSFileProviderManager를 통해 앱의 파일을 Files App에 게시합니다. FileProvider와 달리 iOS 확장은 별도의 바이너리가 필요하며 격리된 프로세스에서 실행됩니다. File Provider Extension은 파일 설명을 위해 NSFileProviderItem을, 폴더 탐색을 위해 NSFileProviderEnumerator를 지원합니다. File Provider Extension을 통한 모바일 앱의 시스템 통합을 통해 사용자는 앱을 열지 않고 Files App에서 앱 파일을 관리할 수 있습니다.
class MyFileProviderExtension: NSFileProviderExtension {
override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
return MyFileProviderItem(identifier: identifier)
}
}
이 예제는 Swift의 File Provider Extension 최소 구현을 보여줍니다. item(for:) 메서드는 식별자로 NSFileProviderItem 객체를 반환합니다 — Files App에서 파일을 표시할 때 시스템이 이를 호출합니다.
자주 묻는 질문
앱 확장은 앱의 기능을 프로세스 너머로 확장하는 별도의 바이너리입니다: Today Widget, Share Extension, Action Extension, Keyboard Extension 및 격리된 환경에서 실행되는 기타 유형.
CallKit은 VoIP 통화를 시스템 통화 인터페이스에 통합하여 잠긴 화면에 표시합니다. PushKit은 사용자에게 표시하지 않고 백그라운드 푸시 알림을 전달합니다 — 수신 통화 정보와 같은 데이터를 처리하기 위해 앱을 깨웁니다.
BroadcastReceiver는 시스템 브로드캐스트 메시지에 반응하는 Android 구성 요소입니다: 장치 부팅(BOOT_COMPLETED), 네트워크 연결(CONNECTIVITY_ACTION), 비행기 모드 변경 및 기타 OS 이벤트.
위젯 인터페이스 생성을 위해 AppWidgetProvider와 RemoteViews를 사용하거나 Kotlin DSL 접근 방식의 Glance API(Jetpack)를 사용하세요. 위젯은 크기와 업데이트 빈도를 지정하는 XML 설명을 통해 매니페스트에 등록됩니다.
Content Provider는 ContentResolver를 통해 앱 간 데이터를 공유하는 Android 구성 요소입니다. 연락처, 미디어 파일 및 다른 앱의 구조화된 데이터에 액세스하는 데 사용됩니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.