Flutterでローカル通知を実装する方法(ios)【初心者向け】

Flutter

はじめに

スマートフォンアプリで重要な機能のひとつにローカル通知があります。ローカル通知は、アプリが起動していなくてもユーザーにメッセージを伝えるための重要な手段です。例えば、ToDoアプリでタスクの期限を通知したり、リマインダーを送るなどのケースで使われます。

今回の記事では、Flutterアプリにローカル通知を実装する方法を、初心者向けにわかりやすく解説していきます。ローカル通知の仕組みを理解し、通知を送るタイミングや設定を学んでいきましょう。


ローカル通知を実装するための準備

Flutterでローカル通知を実装するためには、flutter_local_notificationsというパッケージを利用します。このパッケージは、AndroidやiOS向けに簡単に通知機能を追加することができます。

パッケージのインストール

まず、pubspec.yamlファイルにflutter_local_notificationsパッケージを追加します。

YAML
dependencies:
  flutter:
    sdk: flutter
  flutter_local_notifications: ^12.0.0  # 最新バージョンを指定

その後、以下のコマンドを実行してパッケージをインストールします。

YAML
flutter pub get

iOSの設定

Flutterアプリでローカル通知を使用するためには、プラットフォームごとにいくつかの設定が必要です。

iOSでは、通知の許可を取得するために必要な設定を追加します。

  • ios/Runner/Info.plistファイルに以下を追加します。
XML
	<key>UIBackgroundModes</key>
	<array>
		<string>fetch</string>
		<string>remote-notification</string>
	</array>
  • ios/Runner/AppDelegate.swiftファイルに以下を追加します。
Swift
import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // 追加
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

ローカル通知の実装方法

パッケージをインストールし、必要な設定を終えたら、実際にローカル通知を送るコードを実装していきます。

通知の初期化

まず、ローカル通知を使うための初期設定を行います。main.dartファイルに以下のコードを追加します。

Dart
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

void main() {
  runApp(MyApp());
  initializeNotifications();
}

// 初期化用
void initializeNotifications() async {

  // iOS(Darwin)用の設定
  const DarwinInitializationSettings initializationSettingsDarwin =
      DarwinInitializationSettings(
    requestAlertPermission: true,
    requestBadgePermission: true,
    requestSoundPermission: true,
  );

  // 共通の設定
  final InitializationSettings initializationSettings = InitializationSettings(
    iOS: initializationSettingsDarwin,
  );

  await flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
  );
}

この初期設定により、アプリが起動した際にローカル通知が使える状態になります。

通知を送信する

下記が即時通知を送信するメソッドです。

Dart
  void _showNotification() async {
    const DarwinNotificationDetails iOSPlatformChannelSpecifics =
        DarwinNotificationDetails();

    const NotificationDetails platformChannelSpecifics = NotificationDetails(
      iOS: iOSPlatformChannelSpecifics,
    );

    await flutterLocalNotificationsPlugin.show(
      0,
      '通知タイトル',
      '通知の本文がここに表示されます',
      platformChannelSpecifics,
      payload: 'データ',
    );
  }

このコードでは、flutterLocalNotificationsPlugin.showメソッドを使って即時に通知を送信しています。

スケジュール通知する

下記がスケジュール通知をするメソッドです。

Dart
void _scheduleNotification(TimeOfDay selectedTime) async {
    // 現在の日付に、選択された時間を追加してDateTimeを作成
    final now = DateTime.now();
    final scheduledDate = DateTime(
      now.year,
      now.month,
      now.day,
      selectedTime.hour,
      selectedTime.minute,
    );

    // タイムゾーンを設定
    final tzScheduledDate = tz.TZDateTime.from(scheduledDate, tz.local);

    const DarwinNotificationDetails iOSPlatformChannelSpecifics =
        DarwinNotificationDetails();

    const NotificationDetails platformChannelSpecifics = NotificationDetails(
      iOS: iOSPlatformChannelSpecifics,
    );

    await flutterLocalNotificationsPlugin.zonedSchedule(
      0, // ID
      '時間になりました', // タイトル
      '設定した時間に通知が届きました', // 本文
      tzScheduledDate, // 通知が届く時間
      platformChannelSpecifics,
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents: DateTimeComponents.time, // 毎日同じ時間に通知を繰り返す
    );
  }

このコードでは、flutterLocalNotificationsPlugin.zonedScheduleメソッドを使ってスケジュールを設定しています。

スケジュール通知の実装

指定した時間後に通知を送るスケジュール通知を実装してみます。例えば、画面で指定した時間にに通知を送るコードは次の通りです。

Dart
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tzData;

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

void main() {
  runApp(MyApp());
  initializeNotifications();
}

void initializeNotifications() async {
  tzData.initializeTimeZones(); // タイムゾーンを初期化

  // iOS(Darwin)用の設定
  const DarwinInitializationSettings initializationSettingsDarwin =
      DarwinInitializationSettings(
    requestAlertPermission: true,
    requestBadgePermission: true,
    requestSoundPermission: true,
  );

  // 共通の設定
  final InitializationSettings initializationSettings = InitializationSettings(
    iOS: initializationSettingsDarwin,
  );

  await flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Notification Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TimeOfDay? selectedTime;

  // 時間を選択し、その時間に通知をスケジュールする
  void _scheduleNotification(TimeOfDay selectedTime) async {
    // 現在の日付に、選択された時間を追加してDateTimeを作成
    final now = DateTime.now();
    final scheduledDate = DateTime(
      now.year,
      now.month,
      now.day,
      selectedTime.hour,
      selectedTime.minute,
    );

    // タイムゾーンを設定
    final tzScheduledDate = tz.TZDateTime.from(scheduledDate, tz.local);

    const DarwinNotificationDetails iOSPlatformChannelSpecifics =
        DarwinNotificationDetails();

    const NotificationDetails platformChannelSpecifics = NotificationDetails(
      iOS: iOSPlatformChannelSpecifics,
    );

    await flutterLocalNotificationsPlugin.zonedSchedule(
      0, // ID
      '時間になりました', // タイトル
      '設定した時間に通知が届きました', // 本文
      tzScheduledDate, // 通知が届く時間
      platformChannelSpecifics,
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents: DateTimeComponents.time, // 毎日同じ時間に通知を繰り返す
    );

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('通知を ${selectedTime.format(context)} にスケジュールしました')),
    );
  }

  // 時間を選択するダイアログを表示
  Future<void> _selectTime(BuildContext context) async {
    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );
    if (picked != null) {
      setState(() {
        selectedTime = picked;
      });
      _scheduleNotification(picked);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('通知スケジュールデモ'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => _selectTime(context),
          child: Text('通知時間を選択'),
        ),
      ),
    );
  }
}

これで、アプリ内で特定のイベントに基づいて通知を送ることができます。例えば、リマインダーやタスクの通知などに利用可能です。


まとめ

今回の記事では、Flutterでローカル通知を実装する方法を紹介しました。ローカル通知は、アプリを使わないときにもユーザーにメッセージを届ける重要な機能です。Flutterのflutter_local_notificationsパッケージを使えば、簡単にこの機能を実装することができます。

この記事のポイント

  • flutter_local_notificationsパッケージを使った通知機能の実装。
  • iOSでの必要な設定。
  • 通知の即時送信やスケジュール通知の使い方。

今後は、さらに高度な通知機能や、プッシュ通知を使ったリモート通知についても学んでいきましょう!

今回の内容が参考になれば幸いです!

コメント

タイトルとURLをコピーしました