首页 文章 精选 留言 我的

精选列表

搜索[AI原生],共10000篇文章
优秀的个人博客,低调大师

MASA MAUI Plugin (十)iOS消息推送(原生APNS方式)

背景 MAUI的出现,赋予了广大.Net开发者开发多平台应用的能力,MAUI 是Xamarin.Forms演变而来,但是相比Xamarin性能更好,可扩展性更强,结构更简单。但是MAUI对于平台相关的实现并不完整。所以MASA团队开展了一个实验性项目,意在对微软MAUI的补充和扩展 项目地址https://github.com/BlazorComponent/MASA.Blazor/tree/feature/Maui/src/Masa.Blazor.Maui.Plugin 每个功能都有单独的demo演示项目,考虑到app安装文件体积(虽然MAUI已经集成裁剪功能,但是该功能对于代码本身有影响),届时每一个功能都会以单独的nuget包的形式提供,方便测试,现在项目才刚刚开始,但是相信很快就会有可以交付的内容啦。 前言 本系列文章面向移动开发小白,从零开始进行平台相关功能开发,演示如何参考平台的官方文档使用MAUI技术来开发相应功能。 介绍 Apple 推送通知服务(Apple Push Notification service),简称 APNs。与之前Android使用个推不同,由于APNs国内可用,所以我们可以直接使用APNs来实现远程消息推送,不依赖其他第三方组件和服务。我们这里推送使用的是p8证书,p8证书相对p12证书来讲,更灵活,而且没有p12证书有效期1年的限制。 一、实现方式 一、申请p8证书 https://developer.apple.com/ 1、登录开发者中心,点击右上角Account,找到Keys管理。 2、在顶部点击+号。 3、勾选APNs服务,并输入Key名称,下一步Continue。 4、点击Register。 5、记录Key ID,并下载证书,得到AuthKey_xxxxxxxxxx.p8证书文件。 6、获取Team ID,Account界面点击Membership details 二、编写MAUI实现代码 参考官方文档:https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns 1、首先需要先开启App消息推送的能力 我们新建一个iOSPush 文件夹,并在文件夹下面新建MauiBlazor项目iOSPushSample (由于受打包长度影响,项目名称和文件夹名称,我这里尽量简短。路径长度超过255会导致编译时提示部分文件找不到。) 我们找到Platforms->iOS->Info.plist文件,双击用默认的iOS清单编辑器打开,勾选“启用后台模式”和“远程通知”。这项操作会在Info.plist文件中添加如下信息: <key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array> 在开发环境,你需要以下的额外配置。 如果你的项目已经使用了Entitlements.plist文件,双击打开改文件,并勾选“推送通知”。 如果没有这个文件,那么新建这个文本文件,内容如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>aps-environment</key> <string>development</string> </dict> </plist> 注意:这项配置的目的是在development环境支持推送,如果在项目发布的时候,MAUI不会自动清除,需要手动关闭或注释掉这项配置,否则会报错。 2、编写实现代码 参考文档 https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns 我们首先需要将App注册到APNs并获取唯一的device token。在iOS中需要调用UIApplication 中通过registerForRemoteNotifications() 方法,实现注册,如果注册成功,就可以在delegate的application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 方法中获取device token。如果注册失败,会触发application(_:didFailToRegisterForRemoteNotificationsWithError:) 方法。 Swift代码 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch.you’re UIApplication.shared.registerForRemoteNotifications() return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { self.sendDeviceTokenToServer(data: deviceToken) } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { // Try again later. } 我们开始编写代码 向APNs注册设备 首先在iOS->AppDelegate.cs 类中,重写FinishedLaunching 方法,在应用启动之后进行注册。 [Register("AppDelegate")] public class AppDelegate : MauiUIApplicationDelegate { protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { UNUserNotificationCenter center = UNUserNotificationCenter.Current; var options = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.CriticalAlert; // Request notification permissions from the user center.RequestAuthorization(options, (bool success, NSError error) => { // Handle approval } ); UIApplication.SharedApplication.RegisterForRemoteNotifications(); return base.FinishedLaunching(application, launchOptions); } } 应用启动时应立即请求通知权限,方法是将以下代码添加到FinishedLaunchingAppDelegate 所需通知类型 (UNAuthorizationOptions) 的方法: UNUserNotificationCenter 仅适用于 iOS 10+,但是考虑到基本没人用低于10的版本了,这里我们就不做版本检查了 用户可以批准应用的三个不同级别的通知请求: 横幅显示-Alert 。 声音警报-Sound 。 对应用图标进行错误设置-CriticalAlert。 请求权限结束后我们通过 UIApplication.SharedApplication.RegisterForRemoteNotifications(); 向APNs注册。 注册成功后我们通过application:didRegisterForRemoteNotificationsWithDeviceToken: 方法获取device token,但是由于这个方法是在UIApplication下,但是我们的AppDelegate是继承自 MauiUIApplicationDelegate ,默认没有这个方法,我们可以通过Export特性,导出我们需要的方法,继续在AppDelegate中添加 [Export("application:didFailToRegisterForRemoteNotificationsWithError:")] public void FailedToRegisterForRemoteNotifications(UIKit.UIApplication application, NSError error) { Console.WriteLine("FailedToRegisterForRemoteNotifications"); } [Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")] public void RegisteredForRemoteNotifications(UIKit.UIApplication application, Foundation.NSData deviceToken) { var token = ExtractToken(deviceToken); Preferences.Default.Set("PushToken", token); Console.WriteLine(token); } private string ExtractToken(NSData deviceToken) { if (deviceToken.Length == 0) return null; var result = new byte[deviceToken.Length]; System.Runtime.InteropServices.Marshal.Copy(deviceToken.Bytes, result, 0, (int)deviceToken.Length); return BitConverter.ToString(result).Replace("-", ""); } ExtractToken是将返回的deviceToken解析为推送可用的字符串。 我们通过Preferences.Default.Set将token存储起来,方便在登录等业务中使用。 接收远程推送 接收推送的消息是通过**application:didReceiveRemoteNotification:fetchCompletionHandler:**实现的 [Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")] public void DidReceiveRemoteNotification(UIKit.UIApplication application, NSDictionary userInfo, Action<UIKit.UIBackgroundFetchResult> completionHandler) { foreach (var item in userInfo) { var alertMsg = ((NSDictionary)item.Value)["alert"]; Console.WriteLine($"alertMsg:{alertMsg}"); } Console.WriteLine("DidReceiveRemoteNotification"); } 其实我们在方法内部不需要写任何代码,就可以实现基本的推送功能。但如果想处理推送过来的消息,可以通过NSDictionary类型userInfo中拿到。这里示例从alert中拿到具体的消息内容,并打印。 三、编写演示代码 我们修改Index.razor,通过点击按钮获取设备Token @page "/" <button @onclick="GetDeviceToken">Get Device Token</button> <text>@deviceToken</text> @code { private string deviceToken { get; set; } private void GetDeviceToken() { deviceToken= Preferences.Default.Get("PushToken",string.Empty); } } 四、服务端测试 我们可以通过个推的在线测试工具,配置好p8证书和其他参数。 我这里写了一个命令行的测试程序,这里使用了第三方的PushNotifications.Server包 using PushNotifications.Server.Apple; Console.WriteLine("Hello, World!"); IApnsClient apnsClient = new ApnsClient(new ApnsJwtOptions { CertContent = "-----BEGIN PRIVATE KEY-----\r\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n-----END PRIVATE KEY-----", KeyId = "LUxxxxxxxx", TeamId = "V4xxxxxxxx", BundleId = "com.iOSPush.Sample", UseSandbox = true }); var apnsRequest = new ApnsRequest(ApplePushType.Alert) .AddToken("47006118F8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") .AddSound() .AddAlert("MASA", $"Message @ {DateTime.Now}", $"Message @ {DateTime.Now}"); var apnsResponse = await apnsClient.SendAsync(apnsRequest); Console.ReadKey(); 五、演示效果 可以看出,应用打开的状态不会收到推送,后台运行或者划掉关闭都可以收到通知。 如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

资源下载

更多资源
Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册