2014-03-05 176 views
8

我正在使用Amazon Web Services的Simple Notification Service(SNS)開發iOS應用程序。此時,應用程序將設備註冊到主題,並可以接收發布到主題的推送通知。可以將設備訂閱到許多主題。如何從亞馬遜SNS主題取消訂閱iOS設備?

現在我試圖從特定主題取消訂閱設備,但SNSUnsubscribeRequest需要一個SubscriptionARN。我嘗試使用設備上的EndpointARN,但似乎我必須爲EndpointARN和TopicARN的組合使用額外的SubscriptionARN。我如何獲得這個ARN?

在這篇文章中:How do you get the arn of a subscription?他們要求整個訂戶列表,並將每個EndpointARN與設備的EndpointARN進行比較。這不能是我認爲正確的方式。

訂閱主題

// Check if endpoint exist 
if (endpointARN == nil) { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [[self universalAlertsWithTitle:@"endpointARN not found!" andMessage:@"Please create an endpoint for this device before subscribe to topic"] show]; 
    }); 
    return NO; 
} 

// Create topic if not exist 
NSString *topicARN = [self findTopicARNFor:topic]; 
if (!topicARN) { 
    [self createTopic:topic]; 
    topicARN = [self findTopicARNFor:topic]; 
} 

// Subscribe to topic if exist 
if (topicARN) { 
    SNSSubscribeRequest *subscribeRequest = [[SNSSubscribeRequest alloc] initWithTopicArn:topicARN andProtocol:@"application" andEndpoint:endpointARN]; 
    SNSSubscribeResponse *subscribeResponse = [snsClient subscribe:subscribeRequest]; 
    if (subscribeResponse.error != nil) { 
     NSLog(@"Error: %@", subscribeResponse.error); 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [[self universalAlertsWithTitle:@"Subscription Error" andMessage:subscribeResponse.error.userInfo.description] show]; 
     }); 
     return NO; 
    } 
} 
return YES; 

在主題列表的方法findTopicARNForTopic已經迭代,並比較與主題名稱的後綴。我真的不知道這是否是最佳做法。

退訂主題

NSString *topicARN = [self findTopicARNFor:topic]; 
if (topicARN) { 
    SNSUnsubscribeRequest *unsubscribeRequest = [[SNSUnsubscribeRequest alloc] initWithSubscriptionArn:topicARN]; 
    SNSUnsubscribeResponse *unsubscribeResponse = [snsClient unsubscribe:unsubscribeRequest]; 
    if (unsubscribeResponse.error) { 
     NSLog(@"Error: %@", unsubscribeResponse.error); 
    } 
} 
+1

現在我要求提供整個用戶列表,並將EndpointARN與設備的EndpointARN進行比較。我會在等待8個小時後發佈代碼... –

+0

我遇到了同樣的問題,並且通過訂閱者列表反覆修改了它。我擔心的是安全性:我們如何才能確保只有當前的設備獲得退訂?其他設備是否有可能取消訂閱? – tharkay

+0

另外:您的解決方案和新代碼的答案可能對其他人有幫助。 – tharkay

回答

5

現在我要求整個用戶列表,並使用設備的EndpointARN比較EndpointARN。用下面的方法我得到的訂閱阿爾恩:

- (NSString *)findSubscriptionARNForTopicARN:(NSString *)topicARN 
{ 
    // Iterate over each subscription arn list for a topic arn 
    NSString *nextToken = nil; 
    do { 
     SNSListSubscriptionsByTopicRequest *listSubscriptionRequest = [[SNSListSubscriptionsByTopicRequest alloc] initWithTopicArn:topicARN]; 
     SNSListSubscriptionsByTopicResponse *response = [snsClient listSubscriptionsByTopic:listSubscriptionRequest]; 
     if (response.error) { 
      NSLog(@"Error: %@", response.error); 
      return nil; 
     } 

     // Compare endpoint arn of subscription arn with endpoint arn of this device 
     for (SNSSubscription *subscription in response.subscriptions) { 
      if ([subscription.endpoint isEqualToString:endpointARN]) { 
       return subscription.subscriptionArn; 
      } 
     } 
     nextToken = response.nextToken; 
    } while (nextToken != nil); 
    return nil; 
} 

,並用這種方法我從一個話題刪除設備:

- (void)unsubscribeDeviceFromTopic:(NSString *)topic 
{ 
    NSString *subscriptionARN = [self findSubscriptionARNForTopic:topic]; 
    if (subscriptionARN) { 
     SNSUnsubscribeRequest *unsubscribeRequest = [[SNSUnsubscribeRequest alloc] initWithSubscriptionArn:subscriptionARN]; 
     SNSUnsubscribeResponse *unsubscribeResponse = [snsClient unsubscribe:unsubscribeRequest]; 
     if (unsubscribeResponse.error) { 
      NSLog(@"Error: %@", unsubscribeResponse.error); 
     } 
    } 
} 
1

您還可以存儲SubscriptionArn在SubscribeResponse和使用此值UnSubscribeRequest。

+0

這不好。訂閱請求返回的arn只是「等待確認」。直到訂閱被其他服務確認後纔會創建實際的ARN。 – BrianC