如何在 Xamarin Forms 中实现 CrossPushNotification 插件?
Posted
技术标签:
【中文标题】如何在 Xamarin Forms 中实现 CrossPushNotification 插件?【英文标题】:How to implement the CrossPushNotification plugin in Xamarin Forms? 【发布时间】:2017-02-16 10:57:02 【问题描述】:我在CrossPushNotificationListener
类中实现了IPushNotificationListener
。正如README 文件中所建议的那样。
public class CrossPushNotificationListener : IPushNotificationListener
void IPushNotificationListener.OnError(string message, DeviceType deviceType)
Application.Current.MainPage.DisplayAlert("error", message, "ok");
void IPushNotificationListener.OnMessage(JObject values, DeviceType deviceType)
Application.Current.MainPage.DisplayAlert("message", values.ToString(), "ok");
void IPushNotificationListener.OnRegistered(string token, DeviceType deviceType)
Application.Current.MainPage.DisplayAlert("token", token, "ok");
void IPushNotificationListener.OnUnregistered(DeviceType deviceType)
Application.Current.MainPage.DisplayAlert("unregistered", "", "ok");
bool IPushNotificationListener.ShouldShowNotification()
Application.Current.MainPage.DisplayAlert("should show notification", "", "ok");
return true;
然后在 ios 的 AppDelegate 中初始化 CrossPushNotification 插件。
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
global::Xamarin.Forms.Forms.Init ();
CrossPushNotification.Initialize<CrossPushNotificationListener>();
LoadApplication(new Origination.App ());
return base.FinishedLaunching(app, options);
我还使用适当的覆盖扩展了 AppDelegate,如 PushNotificationApplicationDelegate.txt.pp
文件中所示:
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
if (CrossPushNotification.Current is IPushNotificationHandler)
((IPushNotificationHandler)CrossPushNotification.Current).OnErrorReceived(error);
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
if (CrossPushNotification.Current is IPushNotificationHandler)
((IPushNotificationHandler)CrossPushNotification.Current).OnRegisteredSuccess(deviceToken);
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
if (CrossPushNotification.Current is IPushNotificationHandler)
((IPushNotificationHandler)CrossPushNotification.Current).OnMessageReceived(userInfo);
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
if (CrossPushNotification.Current is IPushNotificationHandler)
((IPushNotificationHandler)CrossPushNotification.Current).OnMessageReceived(userInfo);
然后,在我的共享代码中,用户注册/登录应用程序并进入其主屏幕后,我调用:
CrossPushNotification.Current.Register();
我知道正在执行此方法,因为我收到了请求权限的警报。但是在CrossPushNotificationListener
中实现的IPushNotificationListener
接口中的任何方法都没有被调用。
我在这里错过了什么?
谢谢。
【问题讨论】:
您使用什么服务来发送推送通知?您应该首先检查设备是否已正确注册,并且推送通知已发送到 Apple Push Notification 服务。 CrossPushNotificationListener 中的方法永远不会被调用,所以我没有得到设备令牌。 AppDelegate 中的方法也不是。当我收到权限警报请求时,就会发生注册。这一点让我更加困惑...... 【参考方案1】:使用 DependencyService 的自定义实现。此代码基于Xam.Plugin.PushNotification插件提供的解决方案。
共享项目
接口
public interface INotificationListener
void OnRegister(string deviceToken);
void OnMessage(JObject values);
public interface INotificationService
string Token get;
void Register();
实施
public class NotificationListener : INotificationListener
public void OnMessage(JObject values)
// TOOD: - Handle incoming notifications
public async void OnRegister(string deviceToken)
// TODO: - Register the devices token in the server
public class NotificationManager
private static NotificationManager _current = null;
/// <summary>
/// Shared instance of the Notification Manager
/// </summary>
public static NotificationManager Current
get
if (_current == null)
_current = new NotificationManager();
return _current;
/// <summary>
/// The member responsible for handling notifications
/// </summary>
public static INotificationListener Listener get; private set;
/// <summary>
/// Initializes the Notification Manager with an instance of the specified handler in type T
/// </summary>
/// <typeparam name="T"></typeparam>
public static void Initialize<T>() where T: INotificationListener, new()
Listener = new T();
在适当的时候调用它来向用户请求权限
DependencyService.Get<INotificationService>().Register();
IOS 项目
[assembly: Xamarin.Forms.Dependency(typeof (NotificationService))]
namespace App.iOS.Notifications
public class NotificationService : INotificationService
public string Token
get
return NSUserDefaults.StandardUserDefaults.StringForKey(NotificationKeys.TokenKey);
public void Register()
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
UIUserNotificationType notificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(notificationTypes, new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
else
UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
应用代理
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
LoadApplication(new Origination.App ());
NotificationManager.Initialize<NotificationListener>();
return base.FinishedLaunching(app, options);
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
// Get current device token
var DeviceToken = deviceToken.Description;
if (!string.IsNullOrWhiteSpace(DeviceToken))
DeviceToken = DeviceToken.Trim('<').Trim('>').Replace(" ", "");
// Get previous device token
var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey(NotificationKeys.TokenKey);
// Has the token changed?
if (string.IsNullOrEmpty(oldDeviceToken) || !oldDeviceToken.Equals(DeviceToken))
NotificationManager.Listener.OnRegister(DeviceToken);
// Save new device token
NSUserDefaults.StandardUserDefaults.SetString(DeviceToken, NotificationKeys.TokenKey);
NSUserDefaults.StandardUserDefaults.Synchronize();
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
HandleNotification(userInfo);
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
HandleNotification(userInfo);
#region Handle Notification
private static string DictionaryToJson(NSDictionary dictionary)
NSError error;
var json = NSJsonSerialization.Serialize(dictionary, NSJsonWritingOptions.PrettyPrinted, out error);
return json.ToString(NSStringEncoding.UTF8);
public void HandleNotification(NSDictionary userInfo)
var parameters = new Dictionary<string, object>();
var json = DictionaryToJson(userInfo);
JObject values = JObject.Parse(json);
var keyAps = new NSString("aps");
if (userInfo.ContainsKey(keyAps))
NSDictionary aps = userInfo.ValueForKey(keyAps) as NSDictionary;
if (aps != null)
foreach (var apsKey in aps)
parameters.Add(apsKey.Key.ToString(), apsKey.Value);
JToken temp;
if (!values.TryGetValue(apsKey.Key.ToString(), out temp))
values.Add(apsKey.Key.ToString(), apsKey.Value.ToString());
NotificationManager.Listener.OnMessage(values);
#endregion
【讨论】:
【参考方案2】:在 iOS 上你必须尝试调用:
CrossPushNotification.Initialize<CrossPushNotificationListener>();
之后
LoadApplication(new Origination.App ());
像这样:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
CrossPushNotification.Initialize<CrossPushNotificationListener>();
return base.FinishedLaunching(app, options);
【讨论】:
不是这样的。我最终创建了一个与插件具有类似实现的依赖服务,并且有效。谢谢。 是否可以分享您的实现并选择它作为您问题的答案,有兴趣了解您是如何使用依赖服务进行的吗?以上是关于如何在 Xamarin Forms 中实现 CrossPushNotification 插件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xamarin Forms App 中实现 SSO?
如何在 Xamarin Forms 中实现标记聚类(谷歌地图)
如何使用 Visual Studio for Mac 在 Xamarin.Forms 中实现多目标?