背景
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/r...
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/r...
咱们首先须要将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,欢送分割咱们
WeChat:MasaStackTechOps
QQ:7424099