このブログでは、10.4.1で変更されたiOSの通知機能に関してチュートリアルを交えて解説いたします。
Table of Contents
はじめに
10.4.1よりも前のバージョン(10.4.0も含む)では、iOSアプリの通知機能は、docwikiの「モバイル チュートリアル:通知を使用する(iOS および Android)」に記載されている方法で利用することができました。
例えば、iOSアプリの通知機能を利用する簡単な手順は以下の通りです。
- フォーム上にTNotificationCenterコンポーネントを配置
- プロジェクト」→「オプション」→「バージョン情報」からFMLocalNotificationPermissionの値をtrueに設定
- iOS上でTNotificationCenter.PresentNotificationを実行
しかしながら、10.4.1で同じ手順で通知機能を実装すると、下図のようなエラーが表示されます。
それでは10.4.1で、iOSの通知機能を利用するためには、どうすれば良いのでしょうか。
10.4.1で提供している以下のサンプルプログラムでは、
C:¥Users¥Public¥Documents¥EmbarcaderoStudio¥21.0¥Samples¥Object Pascal¥Mobile¥ Snippets¥Notifications¥SendCancelNotification
実装例が示されていますが、現在のdocwikiでは詳しい解説はありません。
最近、RAD Studio(Delphi/C++Builder)をご利用のお客様からエンバカデロのサポートセンターへ同様なお問い合わせが増えているため、このブログで変更点や実際の使い方も含めまして補足させていただきます。
10.4.1での変更点
上述しましたが、10.4.1よりも前のバージョンで iOSの通知機能を利用する場合は、プロジェクトのバージョン情報で”FMLocalNotificationPermission”の値をtrueに設定する必要がありました。
FMLocalNotificationPermission”の値は、FMX.Platfomr.iOSユニットのTApplicationDelegate.CheckLocalNotificationPermissionメソッドでチェックし、iOS 8以上、かつtrueの場合は、iOSのapiであるUIUserNotificationSettingsを内部で実行してiOSの通知認証を行っていました。
しかしながらiOS 10以降では、UIUserNotificationSettingsの利用は非推奨となっており、10.4.1以降では、iOS10以降で推奨されるUNUserNotificationCenterを利用するように変更されました。
なお、この変更に伴いましてFMLocalNotificationPermissionの項目は廃止されています。10.4.1のプロジェクトのバージョン情報から削除されており、もし手動でこの項目も追加しても無効になっていますので、ご注意ください。
10.4.1では、新たにTNotificationCenterコンポーネントにOnPermissionRequestResultイベントが追加されました。
OnPermissionRequestResultイベントは、RequestPermissionメソッドを実行し、通知を操作するためのアクセス許可を非同期的に要求した後、許可要求の結果を受信するためのイベントです。RequestPermissionメソッドを実行すると、下図のように通知の認証ダイアログが表示されます。
つまり、このダイアログの許可/不許可の結果が、OnPermissionRequestResultイベントで取得できます。
そのため10.4.1以降でiOSの通知機能を利用するためには、RequestPermissionメソッドを呼び出す処理と、OnPermissionRequestResultイベントで通知の認証結果を判断する処理の実装が必要となります。
チュートリアル: 10.4.1でのiOSアプリの通知機能の実装
以下は、Delphi/C++BuilderでiOS通知を行うための簡単な実装手順となります。
(1)10.4.1で新規にマルチデバイスプロジェクトを作成
(2)フォーム上にTNotificationCenterとTButtonを一つずつ配置
(3)通知許可フラグを実装する
あとでOnPermissionRequestResultイベント内で通知の認証結果の判断を行うためのNotification_Permission_Flagフラグを実装します。
Delphiの場合:
1 2 3 4 5 6 7 8 9 10 |
type TForm1 = class(TForm) NotificationCenter1: TNotificationCenter; Button1: TButton; private { private 宣言 } Notification_Permission_Flag: Boolean; public { public 宣言 } end; |
C++Builderの場合:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class TForm1 : public TForm { __published: // IDE で管理されるコンポーネント TButton *Button1; TNotificationCenter *NotificationCenter1; private: // ユーザー宣言 bool Notification_Permission_Flag; public: // ユーザー宣言 __fastcall TForm1(TComponent* Owner); }; |
(4)通知許可を要求するための処理を実装する
通知許可を要求する処理は、通知を実行する前であれば、どのタイミングでも構いません。ここでは、フォームが表示されるOnActivateイベントで実装します。フォームのOnActivateイベントで以下の処理を追加してください。
Delphiの場合:
1 2 3 4 5 6 7 8 9 |
procedure TForm1.FormActivate(Sender: TObject); begin if NotificationCenter1.AuthorizationStatus TAuthorizationStatus.Authorized then begin // 通知リクエスト NotificationCenter1.RequestPermission; end; end; |
C++Builderの場合:
1 2 3 4 5 6 |
void __fastcall TForm1::FormActivate(TObject *Sender) { if (NotificationCenter1->AuthorizationStatus() != TAuthorizationStatus::Authorized) { // 通知リクエスト NotificationCenter1->RequestPermission(); } } |
TAuthorizationStatusには、NotDetermined, Restricted, Denied, Authorizedの4種類があります。ここでは、Authorized(認証)されていないときに、通知許可を要求(RequestPermission)を実行します。
(5)通知の許可要求の結果を受信するためのイベントを実装する
TNotificationCenterのOnPermissionRequestResultイベントで、以下の処理を追加してください。
Delphiの場合:
1 2 3 4 5 6 7 8 |
procedure TForm1.NotificationCenter1PermissionRequestResult(Sender: TObject; const AIsGranted: Boolean); begin if AIsGranted then Notification_Permission_Flag := true else Notification_Permission_Flag := false; end; |
C++Builderの場合:
1 2 3 4 5 6 7 8 |
void __fastcall TForm1::NotificationCenter1PermissionRequestResult(TObject *Sender, const bool AIsGranted) { if (AIsGranted) { Notification_Permission_Flag = true; } else { Notification_Permission_Flag = false; } } |
AIsGrantedの値は、通知ダイアログの結果が渡されます。Trueの場合は許可、Falseの場合は拒否
(6)通知処理を実装する
TButtonのOnClickイベントで、以下の処理を追加してください。
Delphiの場合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
procedure TForm1.Button1Click(Sender: TObject); var MyNotification: TNotification; begin if Notification_Permission_Flag = true then begin // TNotification のインスタンスを作成する MyNotification := NotificationCenter1.CreateNotification; try // 即座にメッセージを送る MyNotification.FireDate := Now; // メッセージを設定する MyNotification.AlertBody := 'iOSのローカル通知テスト'; NotificationCenter1.PresentNotification(MyNotification); finally MyNotification.DisposeOf; end; end else begin ShowMessage('通知は許可されていません。'); end; end; |
C++Builderの場合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void __fastcall TForm1::Button1Click(TObject *Sender) { if (Notification_Permission_Flag) { // TNotification のインスタンスを作成する TNotification *MyNotification = NotificationCenter1->CreateNotification(); try { // 即座にメッセージを送る MyNotification->FireDate = Now(); // メッセージを設定する MyNotification->AlertBody = L"iOSのローカル通知テスト"; NotificationCenter1->PresentNotification(MyNotification); }__finally{ MyNotification->DisposeOf(); } }else{ ShowMessage(L"通知は許可されていません"); } } |
(7)ターゲットプラットホームを”iOSデバイス 64ビット”に切り替えてビルドし、iOSデバイスへ配置する
※プロジェクトの[バージョン情報]で、iOS通知に関する項目の変更は特に必要ありません。
下図は、iOSデバイスでの実行例です。
iOS 14 SDK(Xcode 12)を利用する上での注意点
C++Builder/Delphiで、iOS 14 SDK(Xcode 12)をインポートして利用する場合は、以下の注意が必要です。
- Xcode 12(iOS 14 SDK)でビルドすると、too small (length=0) for architecture arm64エラーが発生する
- Xcode 12(iOS 14 SDK)をインポートしてbcciosarm64でビルドすると、「’_UINTPTR_TYPE_’ は不明な型名です」というエラーが発生する
まとめ
10.4.1では、iOS通知機能に関して以下の変更が行われました。
- FMLocalNotificationPermissionの廃止
- 非推奨であるUIUserNotificationSettingsからUNUserNotificationCenterへ置き換え
- TNotificationCenterコンポーネントにOnPermissionRequestResultイベントを追加
これによってお客様のプログラム側でRequestPermissionメソッドを呼び出す処理と、OnPermissionRequestResultイベントで通知の認証結果を判断する処理の実装が必要となりました。
上記の修正を行う手間がかかるようになりましたが、これによって最新のiOS 14でも動作し、以前のバージョンより適切にiOS通知機能が利用できます。
10.4.1よりも前のバージョンを利用しているお客様はどうかご留意ください。
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition