在iOS上使用标签注册Azure应用服务推送通知的故障排除

7
我本月开始使用Azure应用服务,之前我使用的是Azure移动服务,并且在移动服务中,设备令牌和标签的注册非常简单,但在应用服务中我发现由于安全问题已被移除,所以我必须通过自定义API来实现。我正在使用自定义身份验证(不是Azure身份验证服务(因为我的客户不想要它))与我的数据库一起使用,以便我需要将用户ID设置为标签,以向特定用户发送通知。然而,我遇到了问题,即使设备令牌注册OK(我可以向所有人发送推送而没有标签),但标签仍无法工作,我一直在遵循这些博客文章。

https://blogs.msdn.microsoft.com/writingdata_services/2016/04/14/adding-push-notification-tags-from-a-node-js-backend/

https://blogs.msdn.microsoft.com/writingdata_services/2016/01/22/adding-push-notification-tags-from-an-azure-mobile-apps-client/

我的自定义API(updateNotification.js)

var api = {

    get: (request,response,next) => {
            var push = request.azureMobile.push;
            var installationId = request.query.id;

            push.getInstallation(installationId, function(error, installation, res){
                if (error){                 
                    console.log('An error occurred when retrieving installation : ' + error);
                    response.status(error.statusCode).send(error.detail);                   
                }
                else{
                    // Return an array of current tags.
                    response.json(installation.tags);   
                }               
            }); 
    },

    post: (request, response, next) => {
        var push = request.azureMobile.push;
        var installationId = request.query.id;
        var tags = request.query.userID;

        var updateOperation = [{
            "op": "add",
            "path": "/tags",
            "value": tags.toString()
        }];     

        push.patchInstallation(installationId, updateOperation, function(error, res){
            if(error){
                console.log(error)
                response.status(error.statusCode).send(error.detail);
            }
            else{
                console.log("Success");
                console.log("Tags : " + tags);
                response.status(200).send(tags);
            }
        });
    }
};

module.exports = api;

在我的AppDelegate.swift类中,我正在做这个

func application(application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        let keychain = KeychainSwift()
        let id : NSString = keychain.get("userID")! as String
        let client = MSClient(applicationURLString: "https://XXXX.XXXX.XXX")
        var deviceTokenString = "\(deviceToken)"
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString("<", withString: "")
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(">", withString: "")
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(" ", withString: "-")        

        client.push?.registerDeviceToken(deviceToken, completion: { (error) in
            if let err = error {
                print("ERROR ", err)
            }else{
                client.invokeAPI("updateNotification", body: nil, HTTPMethod: "Post", parameters: ["id" : deviceTokenString , "userID" : id], headers: nil) { (result, response, error) in
                    if response?.statusCode != 200 {
                        NSLog("ERROR %@", error!)
                    } else {
                        print("Tags Successfully Implemented")
                    }
                }
            }
        })

    }

目前一切看起来都很好,在我的控制台中,我可以看到我的用户ID,我的设备令牌和userID像这样(我在中间放了一个X:D对此我很抱歉)

deviceToken = 22afedf6-a08f1ce9-XXXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXX-db431577-2dfbbee1 user ID = 88d06c97-XXXX-XXXX-XXXX-042215c46575

然而,当我尝试使用GET方法查看设备ID的标签时,

    client.invokeAPI("updateNotification", body: nil, HTTPMethod: "GET", parameters: ["id" : deviceTokenString], headers: nil) { (result, response, error) in
             if response?.statusCode != 200 {
                   NSLog("ERROR %@", error!)
             } else {
                  print(result)
             }
   }

我遇到了这个错误:

Error Domain=com.Microsoft.MicrosoftAzureMobile.ErrorDomain Code=-1302 "找不到安装程序。TrackingId:57239dd3-XXXX-XXXX-XXXX-0bd9579c660e_G1,TimeStamp:7/18/2016 8:22:05 PM"

我该如何解决这个错误信息?


1
你能按照诊断指南进行操作吗?如果这没有帮助,你能否复制该问题并在此处粘贴完整的跟踪ID?(这个字符串是随机生成的,不包含任何敏感信息。) - Nikita R.
@NikitaG,这是我的跟踪 ID:c5c802bd-c94f-46f7-b87d-bddbe0e277d4_G6。 - Kaan Baris Bayrak
1个回答

4

好的,在长时间的工作后,这里是解决方案

1.步骤

enter image description here

如果您可以调试通知中心(我建议从Visual Studio 2015 Express等进行调试),您会发现PNS标识符(即我们的设备令牌)全部大写且没有破折号,因此首先需要更改在我们的AppDelegate.swift中的设备令牌代码,如下所示:

deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString("<", withString: "")
deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(">", withString: "")       
deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(" ",withString: "-")
deviceTokenString = deviceTokenString.uppercaseString

//In case of any spaces just guarantee with trim
let trimmedDeviceToken = deviceTokenString.stringByTrimmingCharactersInSet(
    NSCharacterSet.whitespaceAndNewLineCharacterSet()
)

第二步

安装ID和设备令牌是完全不同的东西。您正在将标签推送到安装ID而不是设备令牌,因此需要在客户端代码中获取安装ID。

问题在于,在Azure Mobile SDK for IOS中,您无法使用client.installationId调用安装ID(至少我找不到从MSClient对象获取的方法)。

我的做法是进入框架并找到MSClient.m。然后我意识到安装ID实际上存储在NSUserDefaults中,键为"WindowsAzureMobileServicesInstallationId"。因此,我可以通过NSUser Defaults访问它。

let defaults = NSUserDefaults.standartUserDefaults()
let installationID = defaults.stringForKey("WindowsAzureMobileServicesInstallationId")

在这些步骤之后,你可以实际上将标签注册到安装ID中。以下是应用程序didRegisterForRemoteNotificationsWithDeviceToken方法的结果和完整代码:

    func application(application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        let keychain = KeychainSwift()
        let id : NSString = keychain.get("userID")! as String
        let client = MSClient(applicationURLString: "https://XXXX.XXXX.XXX")
        var deviceTokenString = "\(deviceToken)"
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString("<", withString: "")
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(">", withString: "")
        deviceTokenString = deviceTokenString.stringByReplacingOccurrencesOfString(" ", withString: "")
        deviceTokenString = deviceTokenString.uppercaseString

        //In case of any spaces just guarantee with trim
        let trimmedDeviceToken = deviceTokenString.stringByTrimmingCharactersInSet(
            NSCharacterSet.whitespaceAndNewLineCharacterSet()
        )

        let defaults = NSUserDefaults.standartUserDefaults()
        let installationID = defaults.stringForKey("WindowsAzureMobileServicesInstallationId")

        client.push?.registerDeviceToken(deviceToken, completion: { (error) in
            if let err = error {
                print("ERROR ", err)
            }else{
                client.invokeAPI("updateNotification", body: nil, HTTPMethod: "Post", parameters: ["id" : installationID! , "userID" : id], headers: nil) { (result, response, error) in
                    if response?.statusCode != 200 {
                        NSLog("ERROR %@", error!)
                    } else {
                        print("Tags Successfully Implemented")
                    }
                }
            }
        })

    }

接下来,您还可以通过调用updateNotification的GET方法并发送从NSUserDefaults获取的installationId来检查标签。

在此输入图片描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接