이번 글에서는 Flutter 앱에서 iOS 알림 동작을 세밀하게 설정하는 방법을 다뤄보겠습니다.
특히, 앱 실행 중 알림 표시, 알림음 재생, 앱 아이콘 배지 표시와 같은 기능을 설정하고 iOS 버전에 따라 알림 스타일이 다르게 동작하도록 처리하는 방법을 알아보겠습니다.
먼저 변경 전 코드와 변경 후 코드를 보여드리겠습니다. 변경할 파일은 AppDelegate.swift 입니다.
변경 전, 기존 코드
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
변경 후, 최종 코드
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
if #available(iOS 14.0, *) {
completionHandler([[.banner, .sound, .badge]])
} else {
completionHandler([[.alert, .sound, .badge]])
}
}
}
1. 기본적으로 제공하는 코드 살펴보기
UIKit과 Flutter 라이브러리 가져오기
import UIKit
import Flutter
iOS 앱에서 기본적으로 사용되는 UIKit과 Flutter 앱을 통합하는 데 필요한 Flutter 라이브러리를 가져옵니다.
AppDelegate 클래스 정의
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
AppDelegate 클래스는 앱의 생명주기를 관리합니다. 여기서 FlutterAppDelegate를 상속받아 Flutter와 iOS 생명주기를 연결합니다.
2. 알림 델리게이트 설정
앱이 실행 중일 때 알림 이벤트를 처리할 수 있는 델리게이트 메서드를 호출합니다.
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
}
iOS 10 이상에서만 UNUserNotificationCenter API를 사용할 수 있으므로 #available 조건문으로 버전을 확인합니다.
UNUserNotificationCenter.current().delegate = self를 통해 현재 객체(AppDelegate)를 알림 델리게이트로 지정합니다.
쉽게 말해 UNUserNotificationCenter 는 '알림 관리 센터', 델리게이트는 특정 상황이 발생했을 때 '이렇게 처리해 줘!'라고 미리 정해둔 규칙이라고 생각하면 됩니다.
이렇게 하면 앱이 실행 중일 때 알림 이벤트를 직접 처리할 수 있습니다.
3. 알림 처리 메서드 구현
userNotificationCenter 메서드를 오버라이드하여 알림 기본 동작을 수정해 보겠습니다.
override func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
if #available(iOS 14.0, *) {
completionHandler([.banner, .sound, .badge])
} else {
completionHandler([.alert, .sound, .badge])
}
}
userNotificationCenter() 메서드는 앱이 포그라운드(실행 중) 상태일 때 호출됩니다.
- UNUserNotificationCenter 는 아까 말했듯이 알림을 관리하는 센터라고 보면 됩니다.
- UNNotification 은 실제로 표시될 알림 내용입니다. 시스템이 자동으로 제공합니다.
- UNNotificationPresentationOptions 은 지정한 옵션대로 알림을 표시합니다.
알림 표시 옵션은 completionHandler 메서드를 호출하여 설정할 수 있습니다.
- iOS 14 이상에서는 banner 옵션을 사용해 화면 상단에 배너 형태로 알림을 표시합니다.
- iOS 14 미만에서는 alert 옵션을 사용해 팝업 창 형태로 알림을 표시합니다.
두 경우 모두 sound와 badge 옵션을 추가해 알림음과 배지를 활성화합니다.
4. Flutter 플러그인 등록
GeneratedPluginRegistrant.register(with: self)
Flutter 앱에서 사용하는 플러그인들을 iOS 앱에 등록합니다.
5. 생명주기 메서드 반환
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
이 코드는 앱이 실행될 때 기본적으로 수행하는 초기화 작업을 상위 클래스(super)에서 처리하도록 넘겨주는 역할을 합니다.
FlutterAppDelegate가 제공하는 기본 구현을 호출하여 Flutter 앱과 iOS 시스템을 통합시킵니다. 예를 들어 Flutter 플러그인과 알림 기능 등을 등록하는 거죠.
최종 동작 정리
이 변경 사항을 적용한 결과는 다음과 같습니다.
1. 앱 실행 중에도 알림을 표시합니다.
2. 알림음과 앱 아이콘 배지를 표시합니다.
3. iOS 버전별 알림 스타일을 다르게 제공합니다.
최종 결과는 다음과 같습니다.
변경 전에는 앱이 백그라운드 상태에서만 알림이 왔었습니다.(왼쪽)
변경 후에는 앱이 포그라운드(실행 중) 상태일 때에도 알림이 오는 것을 확인할 수 있습니다.(오른쪽)
마무리
알림 기능을 개발하던 중, 앱을 실행 중인 경우에는 알림이 오지 않는 것을 발견했습니다. 그리고 iOS는 앱이 실행 중인 경우에는 알림을 띄우지 않는다는 걸 알게 되었죠.
이것을 수정하려면 AppDelegate.swift 를 변경할 필요가 있었습니다. 이번 글은 그 과정입니다. 앱 실행 중에 알림을 띄워야 한다면 이 글의 내용을 적용해 보기 바랍니다.
'나는 이렇게 학습한다 > App' 카테고리의 다른 글
Flutter TextField에서 한글 입력 시 자음과 모음이 분리되는 문제 해결하기 (1) | 2024.11.20 |
---|---|
Flutter FloatingActionButton 터치 시 버튼 모양 불일치 해결하기 (0) | 2024.11.19 |
Flutter 앱 아이콘과 이름, 스플래시 화면 설정하기 (0) | 2024.11.18 |
Flutter 앱을 Google Play 스토어에 출시 해보자 (1) | 2024.11.17 |
Flutter의 Wrap 위젯으로 동적 레이아웃 쉽게 구성하기 (0) | 2024.09.06 |