[Flutter] How to Send Notifications on Flutter: Using flutter_local_notification
이번에는 iOS와 Android에서 알림을 보내는 방법에 대해 살펴보겠습니다.
이를 위해 flutter_local_notification이라는 플러그인을 사용하겠습니다.
Creating Project
해당 내용에만 집중하기 위해, 기본 example을 사용하겠습니다.
$ flutter create example
Setting Plugin
pubspec.yaml에 다음과 같이 사용할 플러그인을 명시해 줍니다.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_local_notifications: ^13.0.0
이제 프로젝트에 적용을 해줍니다.
$ flutter pub get
Setting iOS
ios/Runner/AppDelegate.swift 파일을 열고 다음과 같이 수정합니다.
import UIKit
import Flutter
import flutter_local_notifications
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant.register(with: registry)
}
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Setting Android
android/app/build.gradle 파일을 열고 하기의 내용을 찾아 수정해 줍니다.
android {
compileSdkVersion 33
ndkVersion flutter.ndkVersion
defaultConfig {
...
multiDexEnabled true
}
}
Implementing Notification Service
기본 앱에다 바로 구현을 할 수도 있지만, 개인적인 취향으로 분리를 하는 것을 선호하기에 이번 포스팅에서도 그렇게 진행해 보겠습니다.
lib/service/notification_service.dart 파일을 생성해 주세요.
먼저, 서비스 클래스의 뼈대를 만들어 줍니다.
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class NotificationService {
final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
}
플러그인 객체를 클래스 변수로 선언을 해줬습니다.
다음으로 초기화 method를 구현합니다.
Future<void> initNotification() async {
_notificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
AndroidInitializationSettings initializationSettingsAndroid =
const AndroidInitializationSettings('@mipmap/ic_launcher');
DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
onDidReceiveLocalNotification:
(int id, String? title, String? body, String? payload) async {},
);
InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _notificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse:
(NotificationResponse notificationResponse) async {},
);
}
안드로이드와 iOS의 초기화 설정을 만들어 이를 사용하여 초기화를 해 주었습니다.
안드로이드의 경우, 권한 요청 부분을 별도로 해줘야 합니다.
또한, 아이콘 설정을 해줄 수 있는데 알람에 임의의 아이콘을 사용하고 싶으면 android/app/src/main/res/drawable에 넣어주신 후, 아이콘 이름을 AndroidInitializationSettings()에 넣어주시면 됩니다.
만든 초기화 method를 App에서 호출합니다.
import 'package:example/service/notification_service.dart';
class _MyHomePageState extends State<MyHomePage> {
...
@override
void initState() {
super.initState();
NotificationService().initNotification();
}
...
}
어차피 한 번만 초기화 되면 되는 것이라 main()에서 바로 호출해줘도 괜찮지만, context 객체를 사용하게 되는 경우도 있어서 나중을 위해 lifecycle method안에서 호출을 하도록 했습니다.
이제, 알람을 보여주는 method를 구현하겠습니다.
Future<void> showNotification({
int id = 0,
String? title,
String? body,
}) async {
NotificationDetails notificationDetails = const NotificationDetails(
android: AndroidNotificationDetails(
'channelId',
'channelName',
priority: Priority.high,
importance: Importance.max,
channelShowBadge: true,
),
iOS: DarwinNotificationDetails(),
);
return _notificationsPlugin.show(id, title, body, notificationDetails);
}
iOS에 비해, 안드로이드는 설정이 많죠? ㅎㅎ
보면 쉽게 이해할 수 있는 것들이라 설명은 따로 필요없을 것 같아요.
마지막으로 floatingActionButton을 눌렀을 때, 알림이 오도록 해보겠습니다.
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter();
NotificationService().showNotification(
title: 'My Alarm',
body: 'You touched $_counter times.',
);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
Testing
먼저, ios에서 실행을 해보겠습니다.
알림 권한을 요청을 하고, 허용을 하면 버튼을 누를 때 마다 알람이 옵니다.
다음은 안드로이드에서 실행해 보겠습니다.
마찬가지로, 권한을 주면 알람이 잘 오는 것을 확인할 수 있습니다.
안드로이드의 경우 아이콘에 제약 조건이 있는지 기본 플러터 아이콘을 다른 아이콘으로 변경할 경우, 잘 동작하지 않더라고요.
이 부분은 명시된 곳이 따로 없어서 확인해보지 못했습니다.
Wrap Up
이번 포스팅에서는 플러터 앱에서 알람을 보내는 방법에 대해 살펴보았습니다.
타이머를 사용하여 테스트해본 결과 기본적으로 앱이 동작하고 있는 상태에서만 알람을 보낼 수 있고, 앱을 완전히 종료한 상태에서는 알람을 보낼 수 없습니다.
안드로이드의 경우 설정할 것들이 좀 더 많아 복잡하지만, 그만큼 세세하게 컨트롤 할 수 있습니다.
다만, 아이콘의 경우처럼 뭔가의 제약으로 잘 동작하지 않는 부분도 있더라고요.
현재, 14.0.0 버전이 개발 중인데 크게 달라지는 부분은 없는 느낌입니다.