fc2ブログ

記事一覧

ローカル通知をiOS10に対応させる方法 | Xamarin.Forms


以前の記事でスマホの画面上に通知を表示する(ローカル通知/Local Notification)方法をご紹介しました。
しかしながら、iOS10からは、UNUserNotificationCenterを使用して構築しなければならず、大幅な仕様変更になっています。それゆえ今回は仕様変更後のローカル通知の方法についてご紹介いたします。

iPhone7 iOS10
xamarin_ios10_notification_02.png
iPhone6s iOS10
xamarin_ios10_notification_01.png



前提条件
・Windows10 Pro 64Bit
・Visual Studio 2015 Community Update3
・Xamarin 4.4.0.34 (NuGet Xamarin.Forms 2.3.4.247)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.8.0.175



1.PCLでDependenceyServiceの定義を記述

こちらは以前の記事でご紹介したものに、SubTitleを追加しています。
C#
INotificationService.cs
//DependencyServiceから利用する
public interface INotificationService
{
//iOS用の登録
void Regist();
    //通知する
    void On(string title, string subTitle, string body);
    //通知を解除する
    void Off();
}



2.iOS10での記述方法

C#
NotificationService.cs
using System;
using Foundation;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(NotificationService))]
public class NotificationService : INotificationService
{
public void Regist()
{
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// 許可をもらう通知タイプの種類を定義
UNAuthorizationOptions types = UNAuthorizationOptions.Badge | // アイコンバッチ
UNAuthorizationOptions.Sound | // サウンド
UNAuthorizationOptions.Alert; // テキスト

UNUserNotificationCenter.Current.RequestAuthorization(types, (granted, err) => {
// Handle approval
if (err != null)
{
System.Diagnostics.Debug.WriteLine(err.LocalizedFailureReason + System.Environment.NewLine + err.LocalizedDescription);
}
if (granted)
{
}
});
}
}

    public void On(string title, string subTitle, string body)
    {
UIApplication.SharedApplication.InvokeOnMainThread(delegate
{
        var content = new UNMutableNotificationContent();
content.Title = title;
content.Subtitle = title;
content.Body = body;
content.Sound = UNNotificationSound.Default;

var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(5, false); //5秒後に通知、リピートしない
//日時を指定する場合は以下の方法
//NSDateComponents components = new NSDateComponents();
//components.TimeZone = NSTimeZone.DefaultTimeZone;
//components.Year = _notifyDate.LocalDateTime.Year;
//components.Month = _notifyDate.LocalDateTime.Month;
//components.Day = _notifyDate.LocalDateTime.Day;
//components.Hour = _notifyDate.LocalDateTime.Hour;
//components.Minute = _notifyDate.LocalDateTime.Minute;
//components.Second = _notifyDate.LocalDateTime.Second;
//var calendarTrigger = UNCalendarNotificationTrigger.CreateTrigger(components, false);

var requestID = "notifyKey";
content.UserInfo = NSDictionary.FromObjectAndKey(new NSString("notifyValue"), new NSString("notifyKey"));
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);

UNUserNotificationCenter.Current.Delegate = new LocalNotificationCenterDelegate();

// ローカル通知を予約する
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) => {
if (err != null)
{
// Do something with error...
LogUtility.OutPutError(err.LocalizedFailureReason + System.Environment.NewLine + err.LocalizedDescription);
}
});
UIApplication.SharedApplication.ApplicationIconBadgeNumber += 1; // アイコン上に表示するバッジの数値
    });
}
    public void Off()
    {
UIApplication.SharedApplication.InvokeOnMainThread(delegate
{
//全ての送信待ちの通知を削除する場合
//UNUserNotificationCenter.Current.RemoveAllDeliveredNotifications();
//通知時に設定したキーを元に通知情報をキャンセル
UNUserNotificationCenter.Current.RemovePendingNotificationRequests(new string[] { "notifyKey" });
});
    }
}

※iOSでは通知をするためのユーザーの許可設定が必要です。
ユーザーに許可を促すためにRegistのメソッドを予め実行して許可を求めます。
xamarin_notification_ios_01.png



3.使用方法

前回の記事にサブタイトルが追加されたのみで他は同じです。
C#
//PCLのXaml.csファイルのロード時等に記述します。
public ContentPage()
{
//通知設定をiOSに登録
DependencyService.Get<INotificationService>().Regist();
}
//PCLのXaml.csファイルの任意の場所で記述します。
void OnNotificationClick(object sender, EventArgs e)
{
//通知を実行
DependencyService.Get<INotificationService>().On("タイトルテスト", "サブタイトル", "本文テスト");
}



4.アプリ起動時の通知を表示する機能

iOSではアプリが画面上で表示されていると通知が表示されません。そこで以下のように記述するとメッセージで表示してくれるようになります。

LocalNotificationCenterDelegate.cs
public class LocalNotificationCenterDelegate : UNUserNotificationCenterDelegate
{
#region Constructors
public LocalNotificationCenterDelegate()
{
}
#endregion

#region Override Methods
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
// Do something with the notification
Console.WriteLine("Active Notification: {0}", notification);

// Tell system to display the notification anyway or use
// `None` to say we have handled the display locally.
completionHandler(UNNotificationPresentationOptions.Alert);
}
#endregion
}

また、iOSではBackground Fetchバックグラウンドタスクの2種類のバックグラウンド処理がありますが、バックグラウンド処理からローカル通知を呼び出す場合はInvokeOnMainThread内に記述する必要があります。詳しくは以下のURLをご参考ください。
https://itblog.dynaspo.com/blog-entry-173.html



5.仕様・制約

尚、Appleの仕様として、ローカル通知はアプリ毎に64件までしか登録ができないようです。それ以上の通知登録については破棄されているようです。
また、iOS9までのローカル通知でFireDateが過去日の場合は即時発動でしたが、iOS10でのローカル通知でカレンダーを指定した場合、過去日付は通知されないようです。





当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
https://itblog.dynaspo.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。

 入力されていないコメントには返信しませんのであらかじめご了承くださいませ。

※ニックネームでも良いので必ずご入力ください。

    

※必ずご入力ください。

    
    

※必ずご入力ください。

※技術的な質問には環境やエラーについて正確かつ詳細にお教えください。

・正確なエラーの内容

・Windowsのバージョン番号

・Visual Studioのバージョン

・機器の型番

・アプリやソフトのバージョン

    

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Catalina 10.15 / Mojave 10.14 / High Sierra 10.13 / Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
【データベース】
Oracle 10g/9i
SQLServer 2016/2008R2/2005/2000
SQLAnywhere 16/11/8
【BI/レポートツール】
Cognos ReportNet (IBM)
Microsoft PowerBI
ActiveReport (GrapeCity)
CrystalReport
【OCX関連】
GrapeCity InputMan SPREAD MultiRow GridView
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS jQuery IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。