通过AWS SNS发送和接收推送通知

7

我一直在尝试创建一个应用程序,通过AWS SNS发送和接收推送通知。我对API不熟悉,找不到可靠的教程。以下是我设计的发送和接收通知的函数:

func subscribe(deviceTokenString : String)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKey, secretKey: AWSSecretKey)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

    let sns = AWSSNS.defaultSNS()

    let subscribeInput = AWSSNSSubscribeInput()

    subscribeInput.topicArn = SNSTopicARN

    sns.subscribe(subscribeInput).continueWithBlock
    {
        (task) -> AnyObject! in
        if task.error != nil
        {
            print("Subscribed successfully")
            let confirmSubscription = AWSSNSConfirmSubscriptionInput()
            confirmSubscription.topicArn = SNSTopicARN
            confirmSubscription.token = deviceTokenString
            sns.confirmSubscription(confirmSubscription).continueWithBlock
            {
                (task) -> AnyObject! in
                if task.error != nil
                {
                    print("Confirmed subscription")
                    self.sendMessage()
                }
                else
                {
                    print("Subscription confirmation failed with error: \(task.error)")
                }
                return nil
            }
        }
        else
        {
            print("Error while subscribing: \(task.error)")
        }
        return nil
    }

}

func sendMessage()
{
    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    let dict = ["default": "Hello World!", "APNS_SANDBOX": "{\"aps\":{\"alert\": \"HELLO WORLD!\",\"sound\":\"default\", \"badge\":\"1\"} }"]

    do
    {
        let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)
        request.message = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
        request.topicArn = SNSTopicARN
        sns.publish(request).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                print("Error sending mesage: \(task.error)")
            }
            else
            {
                print("Success sending message")
            }
            return nil
        }
    }
    catch
    {
        print("Error on json serialization: \(error)")
    }

}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
    let deviceTokenString = "\(deviceToken)"
        .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString:"<>"))
        .stringByReplacingOccurrencesOfString(" ", withString: "")
    print("deviceTokenString: \(deviceTokenString)")
    subscribe(deviceTokenString)
}

一切似乎都运作良好,控制台上显示“订阅成功”,“确认订阅”和“消息已发送”的日志,但是application:didReceiveRemoteNotificationuserInfo:从未被调用。我做错了什么?


我很惊讶subscribe调用成功了,因为缺少protocols(根据API参考文档,它是必需的)。你应该尝试使用SNS-MobileAnalytics-Sample来了解如何将Amazon SNS移动推送集成到你的应用程序中。另外,你不应该在应用程序中嵌入AWS凭证。此外,通常情况下,你应该从服务器发布推送通知,以避免垃圾邮件。 - Yosuke
1个回答

8

我已经发现我遗漏了一些重点。下面是完全可行的代码片段。

func subscribe(token : String, completionHandler : ((NSError?) -> ())? = nil)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKeySend, secretKey: AWSSecretKeySend)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)

    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

    let sns = AWSSNS.defaultSNS()
    let createPlatformEndpointInput = AWSSNSCreatePlatformEndpointInput()
    createPlatformEndpointInput.token = token
    createPlatformEndpointInput.platformApplicationArn = SNSPlatformApplicationArn

    sns.createPlatformEndpoint(createPlatformEndpointInput).continueWithBlock
    {
        (task) -> AnyObject! in
        if task.error != nil
        {
            print("Error creating platform endpoint: \(task.error)")
            completionHandler?(task.error)
            return nil
        }
        let result = task.result as! AWSSNSCreateEndpointResponse
        let subscribeInput = AWSSNSSubscribeInput()
        subscribeInput.topicArn = SNSTopicARN
        subscribeInput.endpoint = result.endpointArn
        print("Endpoint arn: \(result.endpointArn)")
        subscribeInput.protocols = "application"
        sns.subscribe(subscribeInput).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                completionHandler?(task.error)
                print("Error subscribing: \(task.error)")
                return nil
            }
            print("Subscribed succesfully")
            let subscriptionConfirmInput = AWSSNSConfirmSubscriptionInput()
            subscriptionConfirmInput.token = token
            subscriptionConfirmInput.topicArn = SNSTopicARN
            sns.confirmSubscription(subscriptionConfirmInput).continueWithBlock
            {
                (task) -> AnyObject! in
                if task.error != nil
                {
                    print("Confirmed subscription")
                }
                completionHandler?(task.error)
                return nil
            }
            return nil
        }
        return nil
    }
}

func sendMessage(message : String, type : String = "alert", sound : String = "default", badges : Int = 1, completionHandler : ((NSError?) -> ())? = nil)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKeySend, secretKey: AWSSecretKeySend)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration


    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    let dict = ["default": message, "APNS_SANDBOX": "{\"aps\":{\"\(type)\": \"\(message)\",\"sound\":\"\(sound)\", \"badge\":\"\(badges)\"} }"]

    do
    {
        let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)
        request.message = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
        request.topicArn = SNSTopicARN

        sns.publish(request).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                print("Error sending mesage: \(task.error)")
            }
            else
            {
                print("Success sending message")
            }
            completionHandler?(task.error)
            return nil
        }
    }
    catch
    {
        print("Error on json serialization: \(error)")
    }

}

1
这段代码有些老旧,但仍然是我能找到的唯一一段能够通过Swift发送通知的代码。对于新版本的Swift,需要进行一些更改。 - zeeshan

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