我们使用PushSharp 4.0.10发送iOS推送通知:https://github.com/Redth/PushSharp
最近,我们收到了来自苹果开发者的电子邮件:
“如果您仍然发送带有遗留二进制协议的推送通知,则是时候更新基于HTTP/2的Apple push notifications (APN)提供程序API了。您将能够利用强大的功能,如使用JSON Web令牌的身份验证、改进的错误消息传递和每次通知反馈。为了给您额外的准备时间,升级到APNs提供者API的截止日期已经延长到2021年3月31日。我们建议尽快升级,因为APN在此日期之后将不再支持遗留的二进制协议。”
我的问题是: PushSharp 4.0.10在2021年3月31日后还能工作吗?
发布于 2021-02-22 14:44:09
有关于这个问题的讨论,但是线程已经关闭了。但是在这个线程上仍然有一些建议,您可能想尝试一下。
苹果推送通知服务(APN)将于2020年11月起不再支持遗留的二进制协议 https://github.com/Redth/PushSharp/issues/923
**编辑-2021年3月25日
截止日期已经接近,@Ashita询问了一些代码片段,因此我希望下面的内容可以节省您的时间。
将以下类dotAPNSService添加到项目中。您可以根据您的需要定制此结构。此外,在实现自己的推送通知服务时,我也没有将最好的编码C#标准作为重点。您可以实现LINQ、任务异步等。我测试了这个dotAPNS库,它运行得非常好。对于Android,您仍然可以使用PushSharp。
在实现dotAPNSService助手类之前,从帐户获取以下信息。ApnsJwtOptions值应该是:
BundleId -您的应用程序的包ID。不应该包括特定的主题(即com.myapp而不是com.myapp.voip)。
CertFilePath -从开发人员中心下载的.p8证书的路径。
KeyId -从开发人员帐户中获得的10字符密钥ID。
TeamId -用于开发公司应用程序的10个字符的团队ID。从开发人员帐户中获取此值。
public class dotAPNSService : IDisposable
{
public event EventHandler OnTokenExpiredHandler;
private ApnsJwtOptions options = null;
public dotAPNSService()
{
options = new ApnsJwtOptions()
{
BundleId = "com.xx.xxxx",
CertFilePath = "../../certificate.p8",
KeyId = "The_Key_Id",
TeamId = "The_Team_Id"
};
}
public void SendNotifications(String[] deviceTokens, String title, String body)
{
if (deviceTokens == null || deviceTokens.Length <= 0)
{
return;
}
if (String.IsNullOrEmpty(title))
{
return;
}
if (String.IsNullOrEmpty(body))
{
return;
}
// once you've gathered all the information needed and created an options instance, it's time to call
var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);
// start the process
foreach (String deviceToken in deviceTokens)
{
var push = new ApplePush(ApplePushType.Alert)
.AddAlert(title, body)
.AddToken(deviceToken);
Send(apns, push, deviceToken);
}
}
public void SendSilentNotifications(String[] deviceTokens)
{
try
{
if (deviceTokens == null || deviceTokens.Length <= 0)
{
return;
}
// once you've gathered all the information needed and created an options instance, it's time to call
var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);
// start the process
foreach (String deviceToken in deviceTokens)
{
var push = new ApplePush(ApplePushType.Background)
.AddContentAvailable()
.AddToken(deviceToken);
Send(apns, push, deviceToken);
}
}
finally
{
}
}
private void Send(ApnsClient apns, ApplePush push, String deviceToken)
{
try
{
var response = apns.SendAsync(push);
if (response.Result.Reason == ApnsResponseReason.Success)
{
// the notification has been sent!
}
else
{
Boolean removeToken = false;
switch (response.Result.Reason)
{
case ApnsResponseReason.BadDeviceToken:
removeToken = true;
break;
case ApnsResponseReason.TooManyRequests:
break;
}
// remove the token from database?
if (removeToken)
OnTokenExpired(new ExpiredTokenEventArgs(deviceToken));
}
}
catch (TaskCanceledException)
{
// ERROR - HTTP request timed out, you can use the deviceToken to log the error
}
catch (HttpRequestException ex)
{
// ERROR - HTTP request failed, you can use the deviceToken to log the error
}
}
protected virtual void OnTokenExpired(ExpiredTokenEventArgs args)
{
try
{
EventHandler handler = OnTokenExpiredHandler;
if (handler != null)
{
ISynchronizeInvoke target = handler.Target as ISynchronizeInvoke;
if (target != null && target.InvokeRequired)
target.Invoke(handler, new object[] { this, args });
else
handler(this, args);
}
}
catch (Exception ex)
{
}
}
}
这些是dotAPNSService助手类的命名空间:
using System;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;
using dotAPNS;
为了在项目中使用dotAPNSService助手,只需从数据库中提取令牌,然后将它们传递给它。例如,要发送无声通知:
public void SendScheduledSilentNotifications()
{
try
{
IList<User> users = _accountService.GetUsers(true);
if (users != null && users.Count > 0)
{
List<String> deviceTokens = new List<String>();
foreach (User user in users)
{
if (!String.IsNullOrEmpty(user.DeviceToken))
deviceTokens.Add(user.DeviceToken);
}
if (deviceTokens.Count > 0)
{
using (dotAPNSService service = new dotAPNSService())
{
service.OnTokenExpiredHandler += new EventHandler(OnTokenExpired);
service.SendSilentNotifications(deviceTokens.ToArray());
}
}
}
}
finally
{
}
}
要从数据库中删除过期令牌,可以使用以下命令:
private void OnTokenExpired(object sender, EventArgs e)
{
if (e == null)
return;
if (e.GetType() == typeof(ExpiredTokenEventArgs))
{
var args = (ExpiredTokenEventArgs)e;
User user = _accountService.GetUserByDeviceToken(args.Token);
if (user != null)
{
user.DeviceToken = String.Empty;
Boolean success = !(_accountService.SaveUser(user) == null);
if (success)
// INFO - expired device token has been removed from database
else
// INFO - something went wrong
}
}
}
您可以从这里下载源代码:https://github.com/alexalok/dotAPNS
API现在一次发送数千个无声通知,没有延迟,没有崩溃等。希望这个代码片段能帮助并节省您的时间!
https://stackoverflow.com/questions/65703015
复制相似问题