问题描述
我绝对没有运气在 Xamarin Forms 项目中获得在 iOS 中工作的推送通知。
在 AppDelegate.cs 中,我在 FinishedLaunching 覆盖中调用以下内容:
MSNotificationHub.Start("Endpoint=sb://[redacted].servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=[redacted]","[redacted]");
在用户在应用生命周期中进一步登录后,我还使用他们的用户标签注册用户,如下所示:
public async Task UpdateTags(string token)
{
await Task.Run(() =>
{
try
{
// No point registering tags until the user has signed in and we have a device token
if (CurrentAccount == null)
{
Console.WriteLine($"UpdateTags cancelled: Account is null");
return;
}
var tag = $"user:{CurrentAccount.UserName}";
Console.WriteLine($"Registering tag: {tag}");
MSNotificationHub.AddTag(tag);
}
catch (Exception e)
{
Console.WriteLine($"Error registering tag: {e.ToString()}");
}
});
}
我已经在通知中心正确配置了 Apple (APNS) 设置,使用了令牌认证模式(多次验证了四个字段)。证书(签名身份)是“iOS 分发”,标识符包与我在配置中的完全匹配(不使用通配符),密钥启用了 Apple 推送通知服务 (APNs),并且配置文件具有平台:iOS 和类型:应用商店。
我将应用程序推送到 TestFlight,因为我无法访问物理 Mac(我们使用 Cloud mac 进行开发)。当我从安装了该应用的个人 iPhone 查看设备日志时,我在运行它时看到以下内容:
<Notice>: Registered for push notifications with token: [redacted]
<Notice>: Registering tag: user:[redacted]
日志中根本没有“Error registering tag”或“UpdateTags cancelled”的实例,这告诉我方法调用成功无一例外。但是,当我尝试向空白/空标签或测试用户的特定标签发送测试通知时,没有收到任何通知,消息仅显示“消息已成功发送,但没有匹配的目标”。
此外,当我使用 var registrations = await hub.GetAllRegistrationsAsync(0);
提取所有注册时,我只能看到我在 Android 方面的成功测试中的 FCM (Firebase/Android) 注册。
我完全不知所措,碰壁了,因为没有抛出异常,而且似乎无法解决幕后发生的事情。
这也是我的第二次尝试 - 我使用了更复杂的 SBNotificationHub 实现并获得了相同的结果 - 没有例外,一切看起来都很好。
解决方法
您可以尝试实现 MSInstallationLifecycleDelegate
接口,这将允许您检查安装是否成功或失败保存在后端。
// Set a listener for lifecycle management
MSNotificationHub.SetLifecycleDelegate(new InstallationLifecycleDelegate());
// Implementation of the lifecycle listener.
public class InstallationLifecycleDelegate : MSInstallationLifecycleDelegate
{
public InstallationLifecycleDelegate()
{
}
public override void DidFailToSaveInstallation(MSNotificationHub notificationHub,MSInstallation installation,NSError error)
{
Console.WriteLine($"Save installation failed with exception: {error.LocalizedDescription}");
}
public override void DidSaveInstallation(MSNotificationHub notificationHub,MSInstallation installation)
{
Console.WriteLine($"Installation successfully saved with Installation ID: {installation.InstallationId}");
}
}
,
感谢指向另一个问题的评论,我确定我需要做的就是确保我的标签注册在主 UI 线程上运行。我更新后的代码如下:
<!DOCTYPE html>
<html style="background-color:black; margin:0;padding:0;" lang="en-US">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<meta charset="utf-8"/>
<link rel="icon" href="icon.png"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<meta name="description" content="Description"/>
<title>MyTitle</title>
<style>
a{
color: inherit;
text-decoration: none;
}
*{
margin:0;
padding:0;
}
#heading{
color: white;
text-align: center;
font-size: 24px;
font-weight: 420 bold;
font-family: sans-serif;
text-shadow: 2px 2px red;
margin-right: 10px;
margin-top: 20px;
}
#description{
color: green;
text-align: center;
font-size: 19px;
font-weight: 69 bold;
font-family: serif;
text-shadow: 1px 1px white;
margin-right: 10px;
margin-top: 20px;
}
#cursor{
text-align: initial;
position: absolute;
left: 0;
font-weight: 35;
font-size: 25px;
color: #2E3D48;
-webkit-animation: 1s blink step-end infinite;
-moz-animation: 1s blink step-end infinite;
-ms-animation: 1s blink step-end infinite;
-o-animation: 1s blink step-end infinite;
animation: 1s blink step-end infinite;
}
#field{
color: white;
text-align: center;
font-size: 20px;
}
#fieldDiv{
background-color: #968786;
text-align: center;
width: 100%;
height: 28px;}
@keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: black;
}
}
@-moz-keyframes blink {
from,to {
color: transparent;
}
50% {
color: black;
}
}
@-webkit-keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: black;
}
}
@-ms-keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: black;
}
}
@-o-keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: black;
}
}
#cursorContainer{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#bton{
width: 20px;
height: 20px;
}
</style>
</head>
<body>
<h1 id="heading">
Heading
</h1>
<p id="description">Description</p>
<div id="fieldDiv">
<p id="field"></p><p id="cursorContainer" onclick="hideCursor()"><span id="cursor">|</span></p>
</div>
<br/>
<button id="bton" onclick="change();">
<!--Always add the script on the bottom of the BODY tag since it contains the script-->
<script type="text/javascript">
var marginNum = screen.width/2;
const screenWidth = screen.width;
function checkCtrlA(){
var ctrlPressed = false;
window.addEventListener("keydown",function(e){
if(e.keyCode == 17){
ctrlPressed = true;
}
});
if(ctrlPressed){
window.addEventListener("keydown",function(e){
if(e.keyCode == 65){
hideCursor();
}
})
}
}
window.onload = function(){
const cursor = document.getElementById("cursor");
const widthNeeded = innerWidth/2;
cursor.style.marginLeft = widthNeeded.toString() + "px";
cursor.style.cursor = "default";
};
const divToHide = document.getElementById("fieldDiv");
divToHide.onclick = hideCursor;
function printf(val){
console.log(val);
}
document.getElementById("fieldDiv").addEventListener('click',function(){
const element = document.getElementById("cursor");
element.style.visibility = "hidden";
});
document.getElementById("fieldDiv").addEventListener("mouseover",function(){
const element = document.getElementById("cursor");
element.style.visibility = "hidden";
});
document.getElementById("fieldDiv").addEventListener("mouseout",function(){
const element = document.getElementById("cursor");
element.style.visibility = "visible";
});
var currentText = document.getElementById("field").textContent;
function change(){
movePosCursor();
currentText = document.getElementById("field").textContent += "a";
document.getElementById("cursor").style.visibility = "visible";
}
function movePosCursor(){
const element = document.getElementById("cursor");
marginNum += 5;
var widthInPx = marginNum.toString() + "px";
element.style.marginLeft = widthInPx;
}
function hideCursor(){
const element = document.getElementById("cursor");
element.style.visibility = "hidden";
}
checkCtrlA();
</script>
</body>
</html>