我正在为本地化的跨平台移动应用开发后端,并希望在后端发生某些事件时向用户发送推送通知。
这些应用是使用 xamarin 为 iOS 和 android 开发的,后端是 web-api 2 使用 Azure通知中心。
目前,移动应用使用Installations通过网络API注册通知。通过web-API注册是必要的,因为服务器创建了一个唯一的用户标签,用于在发送消息时识别用户。我目前能够从azure后端的“Debug”部分向已注册的iOS设备发送测试通知。以下是处理注册的代码:
[HttpPut]
[Route("")]
public async Task<IHttpActionResult> CreateOrUpdateDeviceInstallation(DeviceInstallationModel deviceInstallationModel)
{
var installation = new Installation
{
InstallationId = deviceInstallationModel.InstallationId,
PushChannel = deviceInstallationModel.Handle
};
switch (deviceInstallationModel.Platform)
{
case "apns":
installation.Platform = NotificationPlatform.Apns;
break;
case "gcm":
installation.Platform = NotificationPlatform.Gcm;
break;
default:
return BadRequest("The given platform is not supported");
}
installation.Tags = new List<string>{ OwnerId };
//OwnerId is the server generated unique user tag
await _notificationHubClient.CreateOrUpdateInstallationAsync(installation);
return Ok();
}
public class DeviceInstallationModel
{
public string InstallationId { get; set; }
public string Platform { get; set; }
public string Handle { get; set; }
}
我现在需要在后端发生某些事件时发送本地化推送通知。我试图实现这个,而后端不知道有关应用程序的区域设置和应用程序平台的任何信息。据我所知,文档(Cross-Platform-Notifications和localized-notifications),模板将让我实现这一目标。
答案 0 :(得分:2)
要回答1-3,您需要查看Template功能。 (Q1)由于您使用的是移动应用程序,因此移动应用程序Xamarin SDK实际上允许您直接register with templates in Installations。 (Q2)要查看模板在Installation对象中的样子,正文here是一个好地方。 (Q3)要发送,您链接到的教程实际上提供了很好的示例。 对于第四季度,它真的取决于。您可以使用相同的模板来传达不同的消息,因为使用此模板注册的所有用户都将收到这些消息(例如,在cross-plat tutorial中,您可以轻松切换“Hello”,+用户使用另一条消息)。但是如果您需要对这些消息进行本地化等,则需要多个模板。
如果您有任何其他问题,请与我们联系。
答案 1 :(得分:2)
- 如何使用安装完成模板注册?
醇>
正如您在自己的回答中所使用的那样,使用Templates
类的Installation
属性。
- 模板必须如何才能在客户端上进行本地化以及客户必须做些什么才能实现本地化? (或者每个区域设置是否有模板?)
醇>
对需要本地化的文本使用模板参数,并为参数名称添加语言后缀。更确切地说,客户端应该使用具有语言后缀的参数的模板进行注册。
使用英语区域设置的iOS示例:
{"aps":{"alert":"$(message_en)"}}
使用德语区域设置的Android示例:
{"data":{"message":"$(message_de)"}}
- 在不了解客户端平台或区域设置时,后端必须做什么才能发送通知?
醇>
只需发送包含所有可能区域设置中所有参数的模板通知。
假设应用程序仅支持英语和德语的示例:
public void SendMessageA(int recipientUserId)
{
var tagExpression = $"{recipientUserId}";
var parameters = new Dictionary<string, string>()
{
{ "message_en", "This is message A!" },
{ "message_de", "Dies ist Nachricht A!" }
};
_notificationHubClient.SendTemplateNotificationAsync(parameters, tagExpression);
}
public void SendMessageB(int recipientUserId)
{
var tagExpression = $"{recipientUserId}";
var parameters = new Dictionary<string, string>()
{
{ "message_en", "This is message B!" },
{ "message_de", "Dies ist Nachricht B!" }
};
_notificationHubClient.SendTemplateNotificationAsync(parameters, tagExpression);
}
- 我要发送不同的消息(文本)。我是否需要为每条消息提供一个(或更多)模板?
醇>
正如您所看到的,使用此方法,您可以为每个应用实例注册一个模板,并可以从后端发送不同的本地化消息。
当然,你的答案中的方法也有效,但你应该尽可能避免使用标签,因为标签表达是有限的(例如to 6 tags, if the expression contains other operators than OR
)而你更灵活,如果你不这样做将通知的文本硬编码到您的应用中。
答案 2 :(得分:1)
我找到了实现所需行为的解决方案。
出于演示目的,假设客户端可以注册两个不同的通知,即MessageA和MessageB。 MessageA 从客户端标记为“tagForMessageA”,MessageB从客户端标记为“taggedForMessageB”。当客户端应用程序启动或用户更改其语言时,它会调用Web-API并为其希望接收的每条消息指定一个模板(本示例中为messageA和messageB)。 Body包含平台特定的本地化主体,例如:
MessageA,英文iOS
{"aps":{"alert":"This is message A!"}}
或 MessageB,德语android
{"data":{"message":"Dies ist NachrichtB für Android!"}}
这使客户能够决定
现在,这是处理注册的Web-API代码:
[HttpPut]
[Route("")]
public async Task<IHttpActionResult> CreateOrUpdateDeviceInstallation(DeviceInstallationModel deviceInstallationModel)
{
var installation = new Installation
{
InstallationId = deviceInstallationModel.InstallationId,
PushChannel = deviceInstallationModel.Handle,
Tags = new List<string>
{
//Obtain the users id from the database here
},
Templates = new Dictionary<string, InstallationTemplate>()
};
switch (deviceInstallationModel.Platform)
{
case "apns":
installation.Platform = NotificationPlatform.Apns;
break;
case "gcm":
installation.Platform = NotificationPlatform.Gcm;
break;
default:
return BadRequest("The given platform is not supported");
}
foreach (var templateModel in deviceInstallationModel.Templates)
{
if (installation.Templates.ContainsKey(templateModel.MessageIdentifier))
{
return BadRequest("Message identifiers must be unique");
}
installation.Templates.Add(
templateModel.MessageIdentifier,
CreateInstallationTemplateFromModel(templateModel));
}
await _notificationHubClient.CreateOrUpdateInstallationAsync(installation);
return Ok();
}
private static InstallationTemplate CreateInstallationTemplateFromModel(TemplateModel templateModel)
{
return new InstallationTemplate
{
Body = templateModel.Body,
Tags = new List<string> {templateModel.MessageIdentifier}
};
}
public class DeviceInstallationModel
{
public DeviceInstallationModel()
{
Templates= new List<TemplateModel>();
}
public string InstallationId { get; set; }
public string Platform { get; set; }
public string Handle { get; set; }
public List<TemplateModel> Templates { get; set; }
}
public class TemplateModel
{
public string MessageIdentifier { get; set; }
public string Body { get; set; }
}
这是客户必须遵循的惯例:
public class MessageIdentifiers
{
public const string MessageA = "tagForMessageA";
public const string MessageB = "tagForMessageB";
}
此代码处理向客户端发送通知
public void SendMessageA(int recipientUserId)
{
var tagExpression = $"{recipientUserId}&&{MessageIdentifiers.MessageA}";
_notificationHubClient.SendTemplateNotificationAsync(new Dictionary<string, string>(),
tagExpression);
}
public void SendMessageB(int recipientUserId)
{
var tagExpression = $"{recipientUserId}&&{MessageIdentifiers.MessageB}";
_notificationHubClient.SendTemplateNotificationAsync(new Dictionary<string, string>(),
tagExpression);
}