我知道使用同一台设备进行生产和开发,或者涉及带有Azure的Push Notifications和Notifications Hubs,都会出现问题。
我设置方法的方式类似于iOS:
当我在开发中使用该应用程序时,在AppDelegate.cs中,我只是向开发中心注册,例如:
var client = new MobileServiceClient(AppConstants.AZURE_DEVELOPMENT_WEB_API_URL);
当应用程序准备好进行生产时,我在AppDelegate.cs中向生产通知中心注册,例如:
var client = newMobileServiceClient(AppConstants.AZURE_PRODUCTION_WEB_API_URL)
;
我当然会根据情况将Entitlements.plist aps-environment密钥修改为开发或生产版本。
这在一段时间内效果很好,但现在我在这一行中收到一个错误:
try
{
// exception is triggered here:
await client.GetPush().RegisterAsync(deviceToken, templates);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
错误是这样的:
2018-12-17 12:03:19.682 MyApp.iOS[7321:2007760] <!DOCTYPE html>
<html>
<head>
<title>The resource cannot be found.</title>
<meta name="viewport" content="width=device-width" />
<style>
body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;}
p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
@media screen and (max-width: 639px) {
pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
}
@media screen and (max-width: 479px) {
pre { width: 280px; }
}
</style>
</head>
<body bgcolor="white">
<span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>
<h2> <i>The resource cannot be found.</i> </h2></span>
<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">
<b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
<br><br>
<b> Requested URL: </b>/push/installations/53de1cd2-8ba5-403e-950a-f4a1631a5fae<br><br>
<hr width=100% size=1 color=silver>
<b>Version
Information:</b> Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.7.3163.0
</font>
</body>
</html>
<!--
[HttpException]: The controller for path '/push/installations/53de1cd2-8ba5-403e-950a-f4a1631a5fae' was not found or does not implement IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncC
allback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0()
at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
at System.Web.HttpApplication.StepInvoker.<>c__DisplayClass4_0.<Invoke>b__0()
at Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
at System.Web.HttpApplication.<>c__DisplayClass284_0.<OnExecuteRequestStep>b__0(Action nextStepAction)
at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
--><!--
This error page might contain sensitive information because ASP.NET is configured to show verbose error messages using <customErrors mode="Off"
/>. Consider using <customErrors mode="On"/> or <customErrors mode="RemoteOnly"/> in production environments.-->
Thread finished: <Thread Pool> #13
The thread 0xd has exited with code 0 (0x0).
这是我的AppDelegate.cs中的代码:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// This MobileServiceClient has been configured to communicate with the Azure Mobile App and
// Azure Gateway using the application url. You're all set to start working with your Mobile App!
//Microsoft.WindowsAzure.MobileServices.MobileServiceClient MyAppClient = new Microsoft.WindowsAzure.MobileServices.MobileServiceClient(
//"https://myapp.azurewebsites.net");
global::Xamarin.Forms.Forms.Init();
//add azure support
CurrentPlatform.Init();
//add for using local database
string dbName = "shakealarm_db.sqlite";
string dbFolderPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "..", "Library");
string dbFullPath = Path.Combine(dbFolderPath, dbName);
//load application with overloaded constructor for local db path --> add dbFullPath as param to new App()
LoadApplication(new App(dbFullPath, null));
// first request permission to use push notifications
RequestPushPermissionAsync();
// going to store the contents of the notification in the options param
// extract the content when app is active
_launchOptions = options;
return base.FinishedLaunching(app, options);
}
public override void OnActivated(UIApplication uiApplication)
{
base.OnActivated(uiApplication);
//If app was not running and we come from a notification badge, the notification is
if (_launchOptions != null && _launchOptions.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
{
var notification = _launchOptions[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
PresentNotification(notification);
}
_launchOptions = null;
}
private async Task RequestPushPermissionAsync()
{
// Register for any type of notification (local or remote)
var requestResult = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(
UNAuthorizationOptions.Alert
| UNAuthorizationOptions.Badge
| UNAuthorizationOptions.Sound);
// request result produces two items, item1 and item2
// Item1 = approved boolean
bool approved = requestResult.Item1;
NSError error = requestResult.Item2;
if (error == null)
{
//Handle approval
if (!approved)
{
Console.Write("Permission to receive notifications was not granted.");
return;
}
// check if settings have been modified since last run to disallow permission for push notif.
var currentSettings = await UNUserNotificationCenter.Current.GetNotificationSettingsAsync();
if (currentSettings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
{
Console.WriteLine("Permissions were requested in the past but have been revoked(from settings)");
return;
}
// finally register for push notifications
// starts an asycrhonous process, receives a token
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
Console.Write($"Error requesting permissions: {error}.");
}
}
public async override void RegisteredForRemoteNotifications(
UIApplication application, NSData deviceToken)
{
if (deviceToken == null)
{
// can happen in rare conditions
return;
}
Console.WriteLine($"Token received: {deviceToken}");
await SendRegistrationToServerAsync(deviceToken);
}
private async Task SendRegistrationToServerAsync(NSData deviceToken)
{
//this is the template/payload used by iOS. It contains the "messageParam"
// that will be replaced by our service
const string templateBodyAPNS = @"{
""aps"" : {
""alert"" : ""$(messageParam)"",
""mutable-content"": 1
},
}";
var templates = new JObject();
templates["genericMessage"] = new JObject
{
{"body", templateBodyAPNS }
};
// send registration to web api for PRODUCTION
// var client = new MobileServiceClient(MyApp.App.MobileServiceUrl);
// send registration to web api for DEVELOPMENT
var client = new MobileServiceClient(AppConstants.AZURE_DEVELOPMENT_WEB_API_URL);
try
{
// exception triggered here
await client.GetPush().RegisterAsync(deviceToken, templates);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//get the installation id for Development
Console.WriteLine("Installation id1: " + client.GetPush().InstallationId.ToString());
}
因此,我几乎可以确定安装ID存在问题,这是因为我已经从商店下载了该应用,然后在开发中使用了相同的iPhone,并且混合了安装ID /注册以进行推送通知,但是下一步该怎么办?如何重置安装ID?
欢迎任何建议。