Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

AWS SDK for iOS 1.0.4

  • Loading branch information...
commit 71e1ac8eba6732d0b371d6fb0be3e433243e75d7 1 parent 71060a6
amazonwebservices authored
Showing with 3,837 additions and 14 deletions.
  1. BIN  samples/AWSiOSDemoTVM/.DS_Store
  2. +5 −2 samples/HighScores/HighScores/Constants.h
  3. +6 −1 samples/HighScores/HighScores/Constants.m
  4. +2 −0  samples/HighScores/HighScores/HighScoreList.h
  5. +18 −7 samples/HighScores/HighScores/HighScoreList.m
  6. +7 −0 samples/HighScores/HighScores/HighScoresViewController.m
  7. +428 −0 samples/MessageBoard/MessageBoard.html
  8. +323 −0 samples/MessageBoard/MessageBoard.xcodeproj/project.pbxproj
  9. +7 −0 samples/MessageBoard/MessageBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  10. +43 −0 samples/MessageBoard/MessageBoard/Constants.h
  11. +41 −0 samples/MessageBoard/MessageBoard/Constants.m
  12. +27 −0 samples/MessageBoard/MessageBoard/MembersViewController.h
  13. +85 −0 samples/MessageBoard/MessageBoard/MembersViewController.m
  14. +296 −0 samples/MessageBoard/MessageBoard/MembersViewController.xib
  15. +38 −0 samples/MessageBoard/MessageBoard/Message Board-Info.plist
  16. +14 −0 samples/MessageBoard/MessageBoard/Message Board-Prefix.pch
  17. +50 −0 samples/MessageBoard/MessageBoard/MessageBoard.h
  18. +376 −0 samples/MessageBoard/MessageBoard/MessageBoard.m
  19. +30 −0 samples/MessageBoard/MessageBoard/MessageQueueController.h
  20. +118 −0 samples/MessageBoard/MessageBoard/MessageQueueController.m
  21. +294 −0 samples/MessageBoard/MessageBoard/MessageQueueController.xib
  22. +29 −0 samples/MessageBoard/MessageBoard/Message_BoardAppDelegate.h
  23. +84 −0 samples/MessageBoard/MessageBoard/Message_BoardAppDelegate.m
  24. +41 −0 samples/MessageBoard/MessageBoard/Message_BoardViewController.h
  25. +116 −0 samples/MessageBoard/MessageBoard/Message_BoardViewController.m
  26. +2 −0  samples/MessageBoard/MessageBoard/en.lproj/InfoPlist.strings
  27. +444 −0 samples/MessageBoard/MessageBoard/en.lproj/MainWindow.xib
  28. +772 −0 samples/MessageBoard/MessageBoard/en.lproj/Message_BoardViewController.xib
  29. +25 −0 samples/MessageBoard/MessageBoard/main.m
  30. +17 −0 samples/MessageBoard/README.html
  31. +7 −0 samples/S3Uploader/S3Uploader/Constants.h
  32. +4 −0 samples/S3Uploader/S3Uploader/Constants.m
  33. +7 −0 samples/S3Uploader/S3Uploader/S3UploaderViewController.m
  34. +32 −0 src/Amazon.Runtime/AmazonEndpoints.m
  35. +2 −2 src/Amazon.Runtime/AmazonWebServiceClient.m
  36. +13 −0 src/Amazon.S3/Model/S3Region.m
  37. +20 −1 src/include/AmazonEndpoints.h
  38. +1 −1  src/include/AmazonSDKUtil.h
  39. +13 −0 src/include/S3/S3Region.h
View
BIN  samples/AWSiOSDemoTVM/.DS_Store
Binary file not shown
View
7 samples/HighScores/HighScores/Constants.h
@@ -15,8 +15,9 @@
// Constants used to represent your AWS Credentials.
-#define ACCESS_KEY_ID @"CHANGE ME"
-#define SECRET_KEY @"CHANGE ME"
+#define ACCESS_KEY_ID @"CHANGE ME"
+#define SECRET_KEY @"CHANGE ME"
+#define CREDENTIALS_MESSAGE @"AWS Credentials not configured correctly. Please review the README file."
@interface Constants:NSObject {
@@ -24,5 +25,7 @@
+(NSString*)getRandomPlayerName;
+(int)getRandomScore;
++(UIAlertView *)credentialsAlert;
+
@end
View
7 samples/HighScores/HighScores/Constants.m
@@ -18,9 +18,14 @@
@implementation Constants
++(UIAlertView *)credentialsAlert
+{
+ return [[[UIAlertView alloc] initWithTitle:@"Missing Credentials" message:CREDENTIALS_MESSAGE delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
+}
+
+(NSString*)getRandomPlayerName
{
- NSArray *playerNames = [[NSArray alloc] initWithObjects:@"Norm", @"Jim", @"Jason", @"Zach", @"Matt", @"Glenn", @"Will", @"Wade", @"Trevor", @"Jeremy", @"Ryan", @"Matty", @"Steve", @"Pavel", nil];
+ NSArray *playerNames = [[[NSArray alloc] initWithObjects:@"Norm", @"Jim", @"Jason", @"Zach", @"Matt", @"Glenn", @"Will", @"Wade", @"Trevor", @"Jeremy", @"Ryan", @"Matty", @"Steve", @"Pavel", nil] autorelease];
int name1 = arc4random() % [playerNames count];
int name2 = arc4random() % [playerNames count];
View
2  samples/HighScores/HighScores/HighScoreList.h
@@ -29,6 +29,8 @@
int sortMethod;
}
+@property (nonatomic, retain) NSString *nextToken;
+
-(int)highScoreCount;
-(NSArray*)getHighScores;
View
25 samples/HighScores/HighScores/HighScoreList.m
@@ -43,6 +43,10 @@
*/
@implementation HighScoreList
+
+@synthesize nextToken;
+
+
-(id)init
{
self = [super init];
@@ -50,7 +54,7 @@ -(id)init
{
// Initial the SimpleDB Client.
sdbClient = [[AmazonSimpleDBClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
- nextToken = nil;
+ self.nextToken = nil;
sortMethod = NO_SORT;
}
@@ -64,7 +68,7 @@ -(id)initWithSortMethod:(int)theSortMethod
{
// Initial the SimpleDB Client.
sdbClient = [[AmazonSimpleDBClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
- nextToken = nil;
+ self.nextToken = nil;
sortMethod = theSortMethod;
}
@@ -126,10 +130,10 @@ -(NSArray*)getHighScores
@try {
SimpleDBSelectRequest *selectRequest = [[[SimpleDBSelectRequest alloc] initWithSelectExpression:query] autorelease];
selectRequest.consistentRead = YES;
- if ( nextToken != nil ) selectRequest.nextToken = nextToken;
+ if ( self.nextToken != nil ) selectRequest.nextToken = self.nextToken;
SimpleDBSelectResponse *selectResponse = [sdbClient select:selectRequest];
- nextToken = selectResponse.nextToken;
+ self.nextToken = selectResponse.nextToken;
return [self convertItemsToHighScores:selectResponse.items];
}
@@ -144,7 +148,7 @@ -(NSArray*)getHighScores
*/
-(NSArray*)getNextPageOfScores
{
- if ( nextToken == nil ) {
+ if ( self.nextToken == nil ) {
return [NSArray array];
}
else {
@@ -227,7 +231,7 @@ -(void)clearHighScores
*/
-(NSArray*)convertItemsToHighScores:(NSArray*)theItems
{
- NSMutableArray *highScores = [[NSMutableArray alloc] initWithCapacity:[theItems count]];
+ NSMutableArray *highScores = [[[NSMutableArray alloc] initWithCapacity:[theItems count]] autorelease];
for ( SimpleDBItem *item in theItems ) {
[highScores addObject:[self convertSimpleDBItemToHighScore:item]];
}
@@ -240,7 +244,7 @@ -(NSArray*)convertItemsToHighScores:(NSArray*)theItems
*/
-(HighScore*)convertSimpleDBItemToHighScore:(SimpleDBItem*)theItem
{
- return [[HighScore alloc] initWithPlayer:[self getPlayerNameFromItem:theItem] andScore:[self getPlayerScoreFromItem:theItem]];
+ return [[[HighScore alloc] initWithPlayer:[self getPlayerNameFromItem:theItem] andScore:[self getPlayerScoreFromItem:theItem]] autorelease];
}
/*
@@ -305,4 +309,11 @@ -(NSString*)getPaddedScore:(int)theScore
return [pad stringByReplacingCharactersInRange:range withString:scoreValue];
}
+-(void)dealloc
+{
+ [sdbClient release];
+ [nextToken release];
+ [super dealloc];
+}
+
@end
View
7 samples/HighScores/HighScores/HighScoresViewController.m
@@ -20,6 +20,13 @@
@implementation HighScoresViewController
+-(void)viewDidLoad
+{
+ if ( [ACCESS_KEY_ID isEqualToString:@"CHANGE ME"] ) {
+ [[Constants credentialsAlert] show];
+ }
+}
+
-(IBAction)playerSort:(id)sender
{
if ( sortByPlayer.on ) {
View
428 samples/MessageBoard/MessageBoard.html
@@ -0,0 +1,428 @@
+<html>
+<head>
+ <title>Messaging Users with Amazon SNS and Amazon SQS</title>
+ <style type="text/css">
+ table.sample {
+ border-width: 2px;
+ border-spacing: 5px;
+ border-style: dashed;
+ border-color: cornflowerblue;
+ }
+ table.sample td {
+ padding: 5px;
+ }
+ table.sample tr {
+ padding: 5px;
+ }
+ </style>
+</head>
+<body style="padding: 10px">
+ <h1>Messaging Users with Amazon SNS and Amazon SQS using the AWS SDK for iOS and the AWS SDK for Android</h1>
+
+ <center>
+ <table>
+ <tr>
+ <td><img src="http://media.amazonwebservices.com/android-message-board.png"/></td>
+ <td><img src="http://media.amazonwebservices.com/ios-message-board.png"/></td>
+ </tr>
+ </table>
+ </center>
+
+ <h2>Overview</h2>
+
+ <p>
+ This article discusses how mobile applications can use Amazon Web Services to communicate with users via email, short message service (SMS), and other communication channels.
+ The sample code presented here uses <a href="http://aws.amazon.com/sns/">Amazon Simple Notification Service</a> and
+ <a href="http://aws.amazon.com/sqs/">Amazon Simple Queue Service</a>. Amazon Simple Notification Service (Amazon SNS)
+ makes it easy to set up, manage, and send notifications from mobile applications and have these notifications delivered immediately to
+ any users who have chosen to subscribe to them. Amazon SNS provides a highly scalable, flexible, and cost-effective method to
+ implement such notification systems.
+ </p>
+
+ <p>
+ Amazon Simple Queue Service (Amazon SQS), also discussed here, offers a reliable, highly scalable, hosted queue for storing messages.
+ The types of messages supported by Amazon SQS include&mdash;but aren't limited to&mdash;the notification messages sent from Amazon SNS.
+ </p>
+
+ <p>
+ Together, Amazon SNS and Amazon SQS enable developers to create applications that can message large numbers of users in multiple formats quickly and easily.
+ </p>
+
+
+ <p>
+ The sample application described here demostrates how mobile applications can message their users through Amazon SNS and Amazon SQS.
+ The sample demonstrates how to use Amazon SNS to create a topic, subscribe users to that topic, and publish notifications to the topic.
+ Subscribers to the topic can receive their notifications via email, SMS, or an Amazon SQS queue.
+ Amazon SQS and Amazon SNS can also be used to create other types of communication systems not shown here.
+ </p>
+
+
+ <p>
+ This article shows sample code for both the iOS and Android platforms. The complete sample code and project files are included in the AWS
+ SDKs for these mobile platforms. Links to the SDKs are available at the end of this article.
+ <p/>
+
+ <p>
+ To use the AWS SDK for iOS or the AWS SDK for Android, you will need AWS credentials, that is, an Access Key ID and Secret Access Key.
+ If you haven't already signed up for <a href="http://aws.amazon.com/">Amazon Web Services</a> (AWS), you will need to do that first to get your credentials.
+ You can sign up for AWS <a href="https://aws-portal.amazon.com/gp/aws/developer/registration/index.html">here</a>.
+ After you sign up, you can retrieve your credentials at <a href="https://aws-portal.amazon.com/gp/aws/developer/account?ie=UTF8&amp;action=access-key">this page</a>.
+ </p>
+
+
+ <h2>Creating Amazon SQS and Amazon SNS Clients</h2>
+ <p>Making requests to Amazon SNS and Amazon SQS requires creating a <i>client</i> for each service. The code below shows how to create clients for both services on both the iOS and Android platforms.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+AmazonSNSClient snsClient = [[AmazonSNSClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
+AmazonSQSClient sqsClient = [[AmazonSQSClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+AWSCredentials credentials = new BasicAWSCredentials( Constants.ACCESS_KEY_ID, Constants.SECRET_KEY );
+AmazonSNSClient snsClient = new AmazonSNSClient( credentials );
+AmazonSQSClient sqsClient = new AmazonSQSClient( credentials );
+</pre></td></tr>
+ </table>
+ </p>
+ </p>
+
+
+
+ <h2>Topic Creation</h2>
+ <p>Amazon SNS uses <i>topics</i> to route notifications from <i>publishers</i> to <i>subscribers</i>.
+ The term publisher refers to an application that sends notifications; the term subscriber refers to an entity, such as a user, that receives notifications.
+ Topics provide a junction point for publishers and subscribers to communicate with each other.
+ Once a topic is created, subscribers can be added to the topic and receive notifications/messages.
+ The <i>DisplayName</i> attribute is added to a topic to allow notifications to be sent via SMS.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SNSCreateTopicRequest *ctr = [[[SNSCreateTopicRequest alloc] initWithName:TOPIC_NAME] autorelease];
+SNSCreateTopicResponse *response = [snsClient createTopic:ctr];
+
+SNSSetTopicAttributesRequest* st = [[[SNSSetTopicAttributesRequest alloc] initWithTopicArn:response.topicArn andAttributeName:@"DisplayName" andAttributeValue:TOPIC_NAME] autorelease];
+[snsClient setTopicAttributes:st];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+CreateTopicRequest ctr = new CreateTopicRequest( Constants.TOPIC_NAME );
+CreateTopicResult result = snsClient.createTopic( ctr );
+
+SetTopicAttributesRequest tar = new SetTopicAttributesRequest( result.getTopicArn(), "DisplayName", "MessageBoard" );
+this.snsClient.setTopicAttributes( tar );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>Subscribing to Topics</h2>
+ <p>In order for notifications sent to a topic to be received, you have to subscribe an <i>endpoint</i> to that topic. The endpoint corresponds to a recipient.
+ An endpoint is an email address, SMS number, web server, or Amazon SQS queue. If you are using an Amazon SQS queue, it needs to be configured to receive notification messages from Amazon SNS.
+ Once you subscribe an endpoint to a topic and the <b>subscription is confirmed</b>, the endpoint will receive all messages published to that topic.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SNSSubscribeRequest *sr = [[[SNSSubscribeRequest alloc] initWithTopicArn:topicARN andProtocol:@"email" andEndpoint:emailAddress] autorelease];
+[snsClient subscribe:sr];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SubscribeRequest sr = new SubscribeRequest( this.topicARN, "email", email );
+this.snsClient.subscribe( sr );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+ <h2>Listing a Topic's Subscribers</h2>
+ <p>Listing the subscribers for a topic provides the endpoint and corresponding protocol for each subscriber who receives notification via that topic.
+ The protocol for an endpoint depends on the type of endpoint. For example, endpoints that are email addresses have a protocol of SMTP.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SNSListSubscriptionsByTopicRequest *ls = [[[SNSListSubscriptionsByTopicRequest alloc] initWithTopicArn:topicARN] autorelease];
+SNSListSubscriptionsByTopicResponse *response = [snsClient listSubscriptionsByTopic:ls];
+return response.subscriptions;
+ </pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+ListSubscriptionsByTopicRequest ls = new ListSubscriptionsByTopicRequest( this.topicARN );
+ListSubscriptionsByTopicResult response = this.snsClient.listSubscriptionsByTopic( ls );
+return response.getSubscriptions();
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>Publishing Notifications</h2>
+ <p>Publishers send notifications to topics. Once a new notification is published, Amazon SNS attempts to deliver that notification to every endpoint that is subscribed to the topic.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SNSPublishRequest *pr = [[[SNSPublishRequest alloc] initWithTopicArn:topicARN andMessage:theMessage] autorelease];
+[snsClient publish:pr];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+PublishRequest pr = new PublishRequest( this.topicARN, message );
+this.snsClient.publish( pr );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+ <h2>Unsubscribing from Topics</h2>
+ <p>Unsubscribing removes the endpoint from the topic and stops notifications from being received.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SNSUnsubscribeRequest *unsubscribeRequest = [[[SNSUnsubscribeRequest alloc] initWithSubscriptionArn:subscriptionArn] autorelease];
+[snsClient unsubscribe:unsubscribeRequest];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+UnsubscribeRequest unsubscribeRequest = new UnsubscribeRequest( subscriptionArn );
+this.snsClient.unsubscribe( unsubscribeRequest );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+
+ <h2>Creating a Queue</h2>
+ <p>The first task in using Amazon SQS is to create a queue. Once a queue is created it can be subscribed as an endpoint to an Amazon SNS topic.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SQSCreateQueueRequest *cqr = [[[SQSCreateQueueRequest alloc] initWithQueueName:QUEUE_NAME] autorelease];
+SQSCreateQueueResponse *response = [sqsClient createQueue:cqr];
+
+return response.queueUrl
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+CreateQueueRequest cqr = new CreateQueueRequest( Constants.QUEUE_NAME );
+CreateQueueResult result = this.sqsClient.createQueue( cqr );
+return result.getQueueUrl();
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>Subscribing a Queue to a Topic</h2>
+ <p>Here's how to subscribe a queue to a topic.
+ However, for the queue to receive messages, you must also add a policy to the queue. See below.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+NSString *queueArn = [self createMessageQueue];
+
+SNSSubscribeRequest *request = [[[SNSSubscribeRequest alloc] init] autorelease];
+request.endpoint = queueArn;
+request.protocol = @"sqs";
+request.topicArn = topicARN;
+
+[snsClient subscribe:request];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+String queueArn = this.createMessageQueue();
+
+SubscribeRequest request = new SubscribeRequest();
+request.withEndpoint( queueArn ).withProtocol( "sqs" ).withTopicArn( this.topicARN );
+
+this.snsClient.subscribe( request );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>Adding a policy to a Queue</h2>
+ <p>
+ In order for a queue to receive messages from a topic, the queue must have a policy object that specifies that the topic has <b>sqs:SendMessage</b> permission for the queue.
+ For further details see the <a href="http://aws.amazon.com/sns/faqs/#26">Amazon SNS FAQ</a>.
+ For more information about queue policies see the <a href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSExamples.html">Amazon SQS documentation</a>.
+ Once the policy object is created it can be attached to the queue as follows:
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] init] autorelease];
+[attributes setValue:[self generateSqsPolicyForTopic:queueArn] forKey:@"Policy"];
+
+SQSSetQueueAttributesRequest *request = [[[SQSSetQueueAttributesRequest alloc] initWithQueueUrl:theQueueUrl andAttributes:attributes] autorelease];
+[sqsClient setQueueAttributes:request];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+HashMap<String, String> attributes = new HashMap<String, String>();
+attributes.put("Policy", generateSqsPolicyForTopic( queueArn, this.topicARN ) );
+this.sqsClient.setQueueAttributes(new SetQueueAttributesRequest( queueUrl, attributes ) );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>Receiving Messages from a Queue</h2>
+ <p>Now that a message is in the queue, you can receive it, which requires getting it from the queue. When requesting to get a
+ message from the queue, you can't specify which message to get. Instead, you simply specify the maximum number of messages
+ you want to get (up to 10), and Amazon SQS returns up to that maximum number. Because Amazon SQS is a distributed system and
+ the particular queue we're working with here has very few messages in it, the response to the receive request
+ might be empty. Therefore, you should rerun the sample until you get the message. You should design your own
+ application so that it continues to poll the queue until it gets one or more messages.
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SQSReceiveMessageRequest *rmr = [[[SQSReceiveMessageRequest alloc] initWithQueueUrl:queueUrl] autorelease];
+rmr.maxNumberOfMessages = [NSNumber numberWithInt:10];
+rmr.visibilityTimeout = [NSNumber numberWithInt:30];
+
+SQSReceiveMessageResponse *response = [sqsClient receiveMessage:rmr];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+ReceiveMessageRequest rmr = new ReceiveMessageRequest( this.queueUrl );
+rmr.setMaxNumberOfMessages( 10 );
+rmr.setVisibilityTimeout( 30 );
+
+ReceiveMessageResult result = this.sqsClient.receiveMessage( rmr );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+ <h2>Delete Messages from a Queue</h2>
+ <p>Amazon SQS doesn't automatically delete a message after returning it to the application.
+ By default, it keeps the message to protect against the case where the receiving application fails or loses its connection.
+ In these cases, a different application&mdash;or perhaps a new instance of the same application&mdash; might attempt to get the message.</p>
+
+ <p>To delete the message, you must send a separate request. You specify which message to delete by providing the receipt handle that Amazon SQS returned when you received the message.
+ You can delete only one message per call. Deleting the message acknowledges that you've successfully received and processed it.
+
+
+ <ul><li>iOS</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+SQSDeleteMessageRequest *request = [[[SQSDeleteMessageRequest alloc] initWithQueueUrl:queueUrl andReceiptHandle:message.receiptHandle] autorelease];
+[sqsClient deleteMessage:request];
+</pre></td></tr>
+ </table>
+ </p>
+ <ul><li>Android</li></ul>
+ <p style="padding-left:2cm;">
+ <table class="sample"><tr><td align="left" >
+ <pre>
+DeleteMessageRequest request = new DeleteMessageRequest( this.queueUrl, message.getReceiptHandle() );
+this.sqsClient.deleteMessage( request );
+</pre></td></tr>
+ </table>
+ </p>
+
+ </p>
+
+
+
+ <h2>References</h2>
+ <p>A sample app that includes this code is provided with both mobile SDKs. The download links can be found on the following pages:</p>
+
+
+ <ul>
+ <li><a href="http://aws.amazon.com/sdkforios">AWS SDK for iOS</a></li>
+ <li><a href="http://aws.amazon.com/sdkforandroid">AWS SDK for Android</a></li>
+ </ul>
+
+ <p>For more information about using AWS credentials with mobile applications see the following article:</p>
+ <ul>
+ <li><a href="http://aws.amazon.com/articles/SDKs/Android/4611615499399490">Authenticating Users of AWS Mobile Applications with a Token Vending Machine</a></li>
+ </ul>
+
+ <h2>Questions?</h2>
+ <p>Please feel free to ask questions or provide comments in the <a href="https://forums.aws.amazon.com/forum.jspa?forumID=88">Mobile Development Forum</a>.</p>
+</body>
+</html>
View
323 samples/MessageBoard/MessageBoard.xcodeproj/project.pbxproj
@@ -0,0 +1,323 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D03E18DC148CB91F00C122AC /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18C6148CB91F00C122AC /* Constants.m */; };
+ D03E18DD148CB91F00C122AC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D03E18C7148CB91F00C122AC /* InfoPlist.strings */; };
+ D03E18DE148CB91F00C122AC /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = D03E18C9148CB91F00C122AC /* MainWindow.xib */; };
+ D03E18DF148CB91F00C122AC /* Message_BoardViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D03E18CB148CB91F00C122AC /* Message_BoardViewController.xib */; };
+ D03E18E0148CB91F00C122AC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18CD148CB91F00C122AC /* main.m */; };
+ D03E18E1148CB91F00C122AC /* MembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18CF148CB91F00C122AC /* MembersViewController.m */; };
+ D03E18E2148CB91F00C122AC /* MembersViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D03E18D0148CB91F00C122AC /* MembersViewController.xib */; };
+ D03E18E4148CB91F00C122AC /* Message_BoardAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18D4148CB91F00C122AC /* Message_BoardAppDelegate.m */; };
+ D03E18E5148CB91F00C122AC /* Message_BoardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18D6148CB91F00C122AC /* Message_BoardViewController.m */; };
+ D03E18E6148CB91F00C122AC /* MessageBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18D8148CB91F00C122AC /* MessageBoard.m */; };
+ D03E18E7148CB91F00C122AC /* MessageQueueController.m in Sources */ = {isa = PBXBuildFile; fileRef = D03E18DA148CB91F00C122AC /* MessageQueueController.m */; };
+ D03E18E8148CB91F00C122AC /* MessageQueueController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D03E18DB148CB91F00C122AC /* MessageQueueController.xib */; };
+ D054657E1476DBDE00D74192 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D054657D1476DBDE00D74192 /* UIKit.framework */; };
+ D05465801476DBDE00D74192 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D054657F1476DBDE00D74192 /* Foundation.framework */; };
+ D05465821476DBDE00D74192 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D05465811476DBDE00D74192 /* CoreGraphics.framework */; };
+ D0954367148A220B004D1F93 /* AWSiOSSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0954366148A220A004D1F93 /* AWSiOSSDK.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ D03E18C5148CB91F00C122AC /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
+ D03E18C6148CB91F00C122AC /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; };
+ D03E18C8148CB91F00C122AC /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ D03E18CA148CB91F00C122AC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = "<group>"; };
+ D03E18CC148CB91F00C122AC /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Message_BoardViewController.xib; sourceTree = "<group>"; };
+ D03E18CD148CB91F00C122AC /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ D03E18CE148CB91F00C122AC /* MembersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MembersViewController.h; sourceTree = "<group>"; };
+ D03E18CF148CB91F00C122AC /* MembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MembersViewController.m; sourceTree = "<group>"; };
+ D03E18D0148CB91F00C122AC /* MembersViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MembersViewController.xib; sourceTree = "<group>"; };
+ D03E18D1148CB91F00C122AC /* Message Board-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Message Board-Info.plist"; sourceTree = "<group>"; };
+ D03E18D2148CB91F00C122AC /* Message Board-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Message Board-Prefix.pch"; sourceTree = "<group>"; };
+ D03E18D3148CB91F00C122AC /* Message_BoardAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Message_BoardAppDelegate.h; sourceTree = "<group>"; };
+ D03E18D4148CB91F00C122AC /* Message_BoardAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Message_BoardAppDelegate.m; sourceTree = "<group>"; };
+ D03E18D5148CB91F00C122AC /* Message_BoardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Message_BoardViewController.h; sourceTree = "<group>"; };
+ D03E18D6148CB91F00C122AC /* Message_BoardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Message_BoardViewController.m; sourceTree = "<group>"; };
+ D03E18D7148CB91F00C122AC /* MessageBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageBoard.h; sourceTree = "<group>"; };
+ D03E18D8148CB91F00C122AC /* MessageBoard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageBoard.m; sourceTree = "<group>"; };
+ D03E18D9148CB91F00C122AC /* MessageQueueController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageQueueController.h; sourceTree = "<group>"; };
+ D03E18DA148CB91F00C122AC /* MessageQueueController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageQueueController.m; sourceTree = "<group>"; };
+ D03E18DB148CB91F00C122AC /* MessageQueueController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MessageQueueController.xib; sourceTree = "<group>"; };
+ D05465791476DBDE00D74192 /* Message Board.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Message Board.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ D054657D1476DBDE00D74192 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ D054657F1476DBDE00D74192 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D05465811476DBDE00D74192 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ D0954366148A220A004D1F93 /* AWSiOSSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AWSiOSSDK.framework; path = ../../AWSiOSSDK.framework; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D05465761476DBDE00D74192 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D054657E1476DBDE00D74192 /* UIKit.framework in Frameworks */,
+ D05465801476DBDE00D74192 /* Foundation.framework in Frameworks */,
+ D05465821476DBDE00D74192 /* CoreGraphics.framework in Frameworks */,
+ D0954367148A220B004D1F93 /* AWSiOSSDK.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D03E18C4148CB91F00C122AC /* Message Board */ = {
+ isa = PBXGroup;
+ children = (
+ D03E18C5148CB91F00C122AC /* Constants.h */,
+ D03E18C6148CB91F00C122AC /* Constants.m */,
+ D03E18C7148CB91F00C122AC /* InfoPlist.strings */,
+ D03E18C9148CB91F00C122AC /* MainWindow.xib */,
+ D03E18CB148CB91F00C122AC /* Message_BoardViewController.xib */,
+ D03E18CD148CB91F00C122AC /* main.m */,
+ D03E18CE148CB91F00C122AC /* MembersViewController.h */,
+ D03E18CF148CB91F00C122AC /* MembersViewController.m */,
+ D03E18D0148CB91F00C122AC /* MembersViewController.xib */,
+ D03E18D1148CB91F00C122AC /* Message Board-Info.plist */,
+ D03E18D2148CB91F00C122AC /* Message Board-Prefix.pch */,
+ D03E18D3148CB91F00C122AC /* Message_BoardAppDelegate.h */,
+ D03E18D4148CB91F00C122AC /* Message_BoardAppDelegate.m */,
+ D03E18D5148CB91F00C122AC /* Message_BoardViewController.h */,
+ D03E18D6148CB91F00C122AC /* Message_BoardViewController.m */,
+ D03E18D7148CB91F00C122AC /* MessageBoard.h */,
+ D03E18D8148CB91F00C122AC /* MessageBoard.m */,
+ D03E18D9148CB91F00C122AC /* MessageQueueController.h */,
+ D03E18DA148CB91F00C122AC /* MessageQueueController.m */,
+ D03E18DB148CB91F00C122AC /* MessageQueueController.xib */,
+ );
+ name = "Message Board";
+ path = MessageBoard;
+ sourceTree = "<group>";
+ };
+ D054656E1476DBDE00D74192 = {
+ isa = PBXGroup;
+ children = (
+ D03E18C4148CB91F00C122AC /* Message Board */,
+ D054657C1476DBDE00D74192 /* Frameworks */,
+ D054657A1476DBDE00D74192 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ D054657A1476DBDE00D74192 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D05465791476DBDE00D74192 /* Message Board.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ D054657C1476DBDE00D74192 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D0954366148A220A004D1F93 /* AWSiOSSDK.framework */,
+ D054657D1476DBDE00D74192 /* UIKit.framework */,
+ D054657F1476DBDE00D74192 /* Foundation.framework */,
+ D05465811476DBDE00D74192 /* CoreGraphics.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ D05465781476DBDE00D74192 /* Message Board */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D054659A1476DBDE00D74192 /* Build configuration list for PBXNativeTarget "Message Board" */;
+ buildPhases = (
+ D05465751476DBDE00D74192 /* Sources */,
+ D05465761476DBDE00D74192 /* Frameworks */,
+ D05465771476DBDE00D74192 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Message Board";
+ productName = "Message Board";
+ productReference = D05465791476DBDE00D74192 /* Message Board.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D05465701476DBDE00D74192 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = D05465731476DBDE00D74192 /* Build configuration list for PBXProject "MessageBoard" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = D054656E1476DBDE00D74192;
+ productRefGroup = D054657A1476DBDE00D74192 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D05465781476DBDE00D74192 /* Message Board */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D05465771476DBDE00D74192 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D03E18DD148CB91F00C122AC /* InfoPlist.strings in Resources */,
+ D03E18DE148CB91F00C122AC /* MainWindow.xib in Resources */,
+ D03E18DF148CB91F00C122AC /* Message_BoardViewController.xib in Resources */,
+ D03E18E2148CB91F00C122AC /* MembersViewController.xib in Resources */,
+ D03E18E8148CB91F00C122AC /* MessageQueueController.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D05465751476DBDE00D74192 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D03E18DC148CB91F00C122AC /* Constants.m in Sources */,
+ D03E18E0148CB91F00C122AC /* main.m in Sources */,
+ D03E18E1148CB91F00C122AC /* MembersViewController.m in Sources */,
+ D03E18E4148CB91F00C122AC /* Message_BoardAppDelegate.m in Sources */,
+ D03E18E5148CB91F00C122AC /* Message_BoardViewController.m in Sources */,
+ D03E18E6148CB91F00C122AC /* MessageBoard.m in Sources */,
+ D03E18E7148CB91F00C122AC /* MessageQueueController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ D03E18C7148CB91F00C122AC /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D03E18C8148CB91F00C122AC /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ D03E18C9148CB91F00C122AC /* MainWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D03E18CA148CB91F00C122AC /* en */,
+ );
+ name = MainWindow.xib;
+ sourceTree = "<group>";
+ };
+ D03E18CB148CB91F00C122AC /* Message_BoardViewController.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D03E18CC148CB91F00C122AC /* en */,
+ );
+ name = Message_BoardViewController.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ D05465981476DBDE00D74192 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ D05465991476DBDE00D74192 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+ D054659B1476DBDE00D74192 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)\"",
+ "\"$(SRCROOT)/../..\"",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "MessageBoard/Message Board-Prefix.pch";
+ INFOPLIST_FILE = "MessageBoard/Message Board-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ D054659C1476DBDE00D74192 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)\"",
+ "\"$(SRCROOT)/../..\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "MessageBoard/Message Board-Prefix.pch";
+ INFOPLIST_FILE = "MessageBoard/Message Board-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ VALIDATE_PRODUCT = YES;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D05465731476DBDE00D74192 /* Build configuration list for PBXProject "MessageBoard" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D05465981476DBDE00D74192 /* Debug */,
+ D05465991476DBDE00D74192 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D054659A1476DBDE00D74192 /* Build configuration list for PBXNativeTarget "Message Board" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D054659B1476DBDE00D74192 /* Debug */,
+ D054659C1476DBDE00D74192 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D05465701476DBDE00D74192 /* Project object */;
+}
View
7 samples/MessageBoard/MessageBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:Message Board.xcodeproj">
+ </FileRef>
+</Workspace>
View
43 samples/MessageBoard/MessageBoard/Constants.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// This sample App is for demonstration purposes only.
+// It is not secure to embed your credentials into source code.
+// Please read the following article for getting credentials
+// to devices securely.
+// http://aws.amazon.com/articles/Mobile/4611615499399490
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define ACCESS_KEY_ID @"CHANGE ME"
+#define SECRET_KEY @"CHANGE ME"
+#define CONFIRM_SUBSCRIPTION_MESSAGE @"A confirmation must be accepted before messages are received."
+#define QUEUE_NOTICE @"It may take a few minutes before the queue starts receiving messages."
+#define SMS_SUBSCRIPTION_MESSAGE @"SMS Subscritions must include country codes. 1 for US phones."
+#define CREDENTIALS_MESSAGE @"AWS Credentials not configured correctly. Please review the README file."
+
+#define TOPIC_NAME @"MessageBoard"
+#define QUEUE_NAME @"message-board-queue"
+
+@interface Constants:NSObject {
+}
+
++(UIAlertView *)confirmationAlert;
++(UIAlertView *)queueAlert;
++(UIAlertView *)smsSubscriptionAlert;
++(UIAlertView *)credentialsAlert;
+
+@end
View
41 samples/MessageBoard/MessageBoard/Constants.m
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import "Constants.h"
+
+@implementation Constants
+
+
++(UIAlertView *)confirmationAlert
+{
+ return [[[UIAlertView alloc] initWithTitle:@"Confirmation Required" message:CONFIRM_SUBSCRIPTION_MESSAGE delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
+}
+
++(UIAlertView *)queueAlert
+{
+ return [[[UIAlertView alloc] initWithTitle:@"Message Queue" message:QUEUE_NOTICE delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
+}
+
++(UIAlertView *)smsSubscriptionAlert
+{
+ return [[[UIAlertView alloc] initWithTitle:@"SMS Validation" message:SMS_SUBSCRIPTION_MESSAGE delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
+}
+
++(UIAlertView *)credentialsAlert
+{
+ return [[[UIAlertView alloc] initWithTitle:@"Missing Credentials" message:CREDENTIALS_MESSAGE delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
+}
+
+@end
View
27 samples/MessageBoard/MessageBoard/MembersViewController.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import <UIKit/UIKit.h>
+
+// View used to display the subscribers for the topic.
+@interface MembersViewController : UIViewController {
+ IBOutlet UITableView *members;
+}
+
+@property (nonatomic, retain) NSMutableArray *subscribers;
+
+-(IBAction)back:(id)sender;
+
+@end
View
85 samples/MessageBoard/MessageBoard/MembersViewController.m
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import "MembersViewController.h"
+#import "MessageBoard.h"
+
+// View used to display the subscribers for the topic.
+@implementation MembersViewController
+
+@synthesize subscribers;
+
+- (id)init
+{
+ self.subscribers = [[MessageBoard instance] listSubscribers];
+ return [super initWithNibName:@"MembersViewController" bundle:nil];
+}
+
+-(IBAction)back:(id)sender
+{
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 1;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return [self.subscribers count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ // Configure the cell...
+ SNSSubscription *subscriber = [self.subscribers objectAtIndex:indexPath.row];
+ cell.textLabel.text = subscriber.endpoint;
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.detailTextLabel.text = subscriber.protocol;
+
+ return cell;
+}
+
+-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+ SNSSubscription *subscriber = [self.subscribers objectAtIndex:indexPath.row];
+
+ [[MessageBoard instance] removeSubscriber:subscriber.subscriptionArn];
+ [self.subscribers removeObjectAtIndex:indexPath.row];
+
+ NSArray *indexPaths = [NSArray arrayWithObjects:indexPath, nil];
+ [tableView beginUpdates];
+ [tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
+ [tableView endUpdates];
+ }
+}
+
+- (void)dealloc
+{
+ [subscribers release];
+ [super dealloc];
+}
+
+@end
View
296 samples/MessageBoard/MessageBoard/MembersViewController.xib
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1306</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">301</string>
+ </object>
+ <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>IBUINavigationItem</string>
+ <string>IBUITableView</string>
+ <string>IBUIBarButtonItem</string>
+ <string>IBUIView</string>
+ <string>IBUINavigationBar</string>
+ <string>IBProxyObject</string>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUITableView" id="128099121">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 44}, {320, 416}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUISeparatorStyle">1</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">22</float>
+ <float key="IBUISectionFooterHeight">22</float>
+ </object>
+ <object class="IBUINavigationBar" id="995117190">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">290</int>
+ <string key="NSFrameSize">{320, 44}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="128099121"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableArray" key="IBUIItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUINavigationItem" id="973890239">
+ <reference key="IBUINavigationBar" ref="995117190"/>
+ <string key="IBUITitle">Title</string>
+ <object class="IBUIBarButtonItem" key="IBUILeftBarButtonItem" id="503531293">
+ <string key="IBUITitle">Back</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUINavigationItem" ref="973890239"/>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrame">{{0, 20}, {320, 460}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="995117190"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">back:</string>
+ <reference key="source" ref="503531293"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">9</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">members</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="128099121"/>
+ </object>
+ <int key="connectionID">10</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="128099121"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="128099121"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="995117190"/>
+ <reference ref="128099121"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="128099121"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="995117190"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="973890239"/>
+ </object>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="973890239"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="503531293"/>
+ </object>
+ <reference key="parent" ref="995117190"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="503531293"/>
+ <reference key="parent" ref="973890239"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>7.IBPluginDependency</string>
+ <string>8.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MembersViewController</string>
+ <string>UIResponder</string>
+ <string>{{556, 412}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">12</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MembersViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">back:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">back:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">back:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">members</string>
+ <string key="NS.object.0">UITableView</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">members</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">members</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/MembersViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">301</string>
+ </data>
+</archive>
View
38 samples/MessageBoard/MessageBoard/Message Board-Info.plist
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.amazon.aws.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
View
14 samples/MessageBoard/MessageBoard/Message Board-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'Message Board' target in the 'Message Board' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iPhone SDK 3.0 and later."
+#endif
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+ #import <Foundation/Foundation.h>
+#endif
View
50 samples/MessageBoard/MessageBoard/MessageBoard.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import <AWSiOSSDK/SNS/AmazonSNSClient.h>
+#import <AWSiOSSDK/SQS/AmazonSQSClient.h>
+
+@interface MessageBoard : NSObject {
+ AmazonSNSClient *snsClient;
+ AmazonSQSClient *sqsClient;
+ NSString *topicARN;
+ NSString *queueUrl;
+}
+
++(MessageBoard*)instance;
+
+-(id)init;
+-(NSString*)createTopic;
+-(void)deleteTopic;
+-(NSString*)findTopicArn;
+-(void)subscribeEmail:(NSString*)emailAddress;
+-(void)subscribeSms:(NSString*)smsNumber;
+-(void)post:(NSString*)theMessage;
+-(NSMutableArray*)listSubscribers;
+-(void)removeSubscriber:(NSString*)subscriptionArn;
+
+-(NSString*)findQueueUrl;
+-(NSMutableArray*)getMessagesFromQueue;
+-(void)subscribeQueue;
+-(NSString*)createQueue;
+-(void)deleteQueue;
+-(NSString*)getQueueArn:(NSString*)queueUrl;
+-(void)addPolicyToQueueForTopic:(NSString*)queueUrl queueArn:(NSString*)queueArn;
+-(NSString*)generateSqsPolicyForTopic:(NSString*)queueArn;
+-(void)deleteMessageFromQueue:(SQSMessage*)message;
+
+@end
View
376 samples/MessageBoard/MessageBoard/MessageBoard.m
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+
+#import "MessageBoard.h"
+#import "Constants.h"
+
+
+
+// This singleton class provides all the functionality to manipulate the Amazon
+// SNS Topic and Amazon SQS Queue used in this sample application.
+@implementation MessageBoard
+
+
+static MessageBoard* _instance = nil;
+
++(MessageBoard*)instance
+{
+ @synchronized([MessageBoard class])
+ {
+ if (!_instance) {
+ [[self alloc] init];
+ }
+
+ return _instance;
+ }
+
+ return nil;
+}
+
++(id)alloc
+{
+ @synchronized([MessageBoard class])
+ {
+ NSAssert(_instance == nil, @"Attempted to allocate a second instance of a singleton.");
+ _instance = [super alloc];
+ return _instance;
+ }
+
+ return nil;
+}
+
+-(id)init {
+ self = [super init];
+ if (self != nil) {
+ snsClient = [[AmazonSNSClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
+ sqsClient = [[AmazonSQSClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
+
+ // Find the Topic for this App or create one.
+ topicARN = [[self findTopicArn] retain];
+ if ( topicARN == nil ) {
+ topicARN = [[self createTopic] retain];
+ }
+
+ // Find the Queue for this App or create one.
+ queueUrl = [[self findQueueUrl] retain];
+ if ( queueUrl == nil ) {
+ queueUrl = [[self createQueue] retain];
+
+ // Allow time for the queue to be created.
+ [NSThread sleepForTimeInterval:4.0];
+
+ [self subscribeQueue];
+ }
+ }
+
+ return self;
+}
+
+-(NSString*)createTopic
+{
+ @try {
+ SNSCreateTopicRequest *ctr = [[[SNSCreateTopicRequest alloc] initWithName:TOPIC_NAME] autorelease];
+ SNSCreateTopicResponse *response = [snsClient createTopic:ctr];
+
+ // Adding the DisplayName attribute to the Topic allows for SMS notifications.
+ SNSSetTopicAttributesRequest* st = [[[SNSSetTopicAttributesRequest alloc] initWithTopicArn:response.topicArn andAttributeName:@"DisplayName" andAttributeValue:TOPIC_NAME] autorelease];
+ [snsClient setTopicAttributes:st];
+
+ return response.topicArn;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return nil;
+ }
+}
+
+-(void)subscribeEmail:(NSString*)emailAddress
+{
+ @try {
+ SNSSubscribeRequest *sr = [[[SNSSubscribeRequest alloc] initWithTopicArn:topicARN andProtocol:@"email" andEndpoint:emailAddress] autorelease];
+ [snsClient subscribe:sr];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(void)subscribeSms:(NSString*)smsNumber
+{
+ @try {
+ SNSSubscribeRequest *sr = [[[SNSSubscribeRequest alloc] initWithTopicArn:topicARN andProtocol:@"sms" andEndpoint:smsNumber] autorelease];
+ [snsClient subscribe:sr];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(void)subscribeQueue
+{
+ @try {
+ NSString *queueArn = [self getQueueArn:queueUrl];
+
+ SNSSubscribeRequest *request = [[[SNSSubscribeRequest alloc] initWithTopicArn:topicARN andProtocol:@"sqs" andEndpoint:queueArn] autorelease];
+ [snsClient subscribe:request];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(NSMutableArray*)listSubscribers
+{
+ @try {
+ SNSListSubscriptionsByTopicRequest *ls = [[[SNSListSubscriptionsByTopicRequest alloc] initWithTopicArn:topicARN] autorelease];
+ SNSListSubscriptionsByTopicResponse *response = [snsClient listSubscriptionsByTopic:ls];
+ return response.subscriptions;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return [NSArray array];
+ }
+}
+
+// Unscribe an endpoint from the topic.
+-(void)removeSubscriber:(NSString*)subscriptionArn
+{
+ @try {
+ SNSUnsubscribeRequest *unsubscribeRequest = [[[SNSUnsubscribeRequest alloc] initWithSubscriptionArn:subscriptionArn] autorelease];
+ [snsClient unsubscribe:unsubscribeRequest];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+// Post a notification to the topic.
+-(void)post:(NSString*)theMessage;
+{
+ @try {
+ if ( [theMessage isEqualToString:@"wipe"] ) {
+ [self deleteQueue];
+ [self deleteTopic];
+ }
+ else {
+ SNSPublishRequest *pr = [[[SNSPublishRequest alloc] initWithTopicArn:topicARN andMessage:theMessage] autorelease];
+ [snsClient publish:pr];
+ }
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(void)deleteTopic
+{
+ @try {
+ SNSDeleteTopicRequest* dtr = [[[SNSDeleteTopicRequest alloc] initWithTopicArn:topicARN] autorelease];
+ [snsClient deleteTopic:dtr];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(void)deleteQueue
+{
+ @try {
+ SQSDeleteQueueRequest *request = [[[SQSDeleteQueueRequest alloc] initWithQueueUrl:queueUrl] autorelease];
+ [sqsClient deleteQueue:request];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+-(NSString*)createQueue
+{
+ @try {
+ SQSCreateQueueRequest *cqr = [[[SQSCreateQueueRequest alloc] initWithQueueName:QUEUE_NAME] autorelease];
+ SQSCreateQueueResponse *response = [sqsClient createQueue:cqr];
+
+ NSString *queueArn = [self getQueueArn:response.queueUrl];
+ [self addPolicyToQueueForTopic:response.queueUrl queueArn:queueArn];
+
+ return response.queueUrl;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return nil;
+ }
+}
+
+-(NSMutableArray*)getMessagesFromQueue
+{
+ @try {
+ SQSReceiveMessageRequest *rmr = [[[SQSReceiveMessageRequest alloc] initWithQueueUrl:queueUrl] autorelease];
+ rmr.maxNumberOfMessages = [NSNumber numberWithInt:10];
+ rmr.visibilityTimeout = [NSNumber numberWithInt:30];
+
+ SQSReceiveMessageResponse *response = nil;
+ NSMutableArray *allMessages = [[[NSMutableArray alloc] init] autorelease];
+ do {
+ response = [sqsClient receiveMessage:rmr];
+ [allMessages addObjectsFromArray:response.messages];
+ [NSThread sleepForTimeInterval:1.0];
+ }
+ while ( [response.messages count] != 0 );
+
+ return allMessages;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return [NSArray array];
+ }
+}
+
+-(void)deleteMessageFromQueue:(SQSMessage*)message
+{
+ @try {
+ SQSDeleteMessageRequest *request = [[[SQSDeleteMessageRequest alloc] initWithQueueUrl:queueUrl andReceiptHandle:message.receiptHandle] autorelease];
+ [sqsClient deleteMessage:request];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+// Get the QueueArn attribute from the Queue. The QueueArn is necessary for create a policy on the queue
+// that allows for messages from the Amazon SNS Topic.
+-(NSString*)getQueueArn:(NSString*)theQueueUrl
+{
+ @try {
+ SQSGetQueueAttributesRequest *gqar = [[[SQSGetQueueAttributesRequest alloc] initWithQueueUrl:theQueueUrl] autorelease];
+ [gqar.attributeNames addObject:@"QueueArn"];
+
+ SQSGetQueueAttributesResponse *response = [sqsClient getQueueAttributes:gqar];
+
+ return [response.attributes valueForKey:@"QueueArn"];
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return nil;
+ }
+}
+
+// Add a policy to a specific queue by setting the queue's Policy attribute.
+// Assigning a policy to the queue is necessary as described in Amazon SNS' FAQ:
+// http://aws.amazon.com/sns/faqs/#26
+-(void)addPolicyToQueueForTopic:(NSString*)theQueueUrl queueArn:(NSString*)queueArn
+{
+ @try {
+ NSMutableDictionary *attributes = [[[NSMutableDictionary alloc] init] autorelease];
+ [attributes setValue:[self generateSqsPolicyForTopic:queueArn] forKey:@"Policy"];
+
+ SQSSetQueueAttributesRequest *request = [[[SQSSetQueueAttributesRequest alloc] initWithQueueUrl:theQueueUrl andAttributes:attributes] autorelease];
+ [sqsClient setQueueAttributes:request];
+ // It can take some time for policy to propagate to the queue.
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ }
+}
+
+// Creates the policy object that is necessary to allow the topic to send message to the queue. The topic will
+// send all topic notifications to the queue.
+-(NSString*)generateSqsPolicyForTopic:(NSString*)queueArn
+{
+ NSMutableString *policy = [[NSMutableString alloc] initWithCapacity:256];
+
+ [policy appendString:@"{"];
+ [policy appendString:[[[NSString alloc] initWithFormat:@"\"Version\":\"2008-10-17\","] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@"\"Id\":\"%@/policyId\",", queueArn] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@"\"Statement\": ["] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" {"] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Sid\":\"%@/statementId\",", queueArn] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Effect\":\"Allow\","] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Principal\":{\"AWS\":\"*\"},"] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Action\":\"SQS:SendMessage\","] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Resource\": \"%@\",", queueArn] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"Condition\":{"] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" \"StringEquals\":{\"aws:SourceArn\":\"%@\"}", topicARN] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" }"] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@" }"] autorelease]];
+ [policy appendString:[[[NSString alloc] initWithFormat:@"]"] autorelease]];
+ [policy appendString:@"}"];
+
+ return [policy autorelease];
+}
+
+// Determines if a topic exists with the given topic name.
+// The topic name is assigned in the Constants.h file.
+-(NSString*)findTopicArn
+{
+ @try {
+ NSString *topicNameToFind = [NSString stringWithFormat:@":%@", TOPIC_NAME];
+ NSString *nextToken = nil;
+ do {
+ SNSListTopicsRequest *listTopicsRequest = [[[SNSListTopicsRequest alloc] initWithNextToken:nextToken] autorelease];
+ SNSListTopicsResponse *response = [snsClient listTopics:listTopicsRequest];
+
+ for ( SNSTopic *topic in response.topics ) {
+ if ( [topic.topicArn hasSuffix:topicNameToFind] ) {
+ return topic.topicArn;
+ }
+ }
+
+ nextToken = response.nextToken;
+ }
+ while ( nextToken != nil );
+
+ return nil;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return nil;
+ }
+}
+
+// Determine if a queue exists with the given queue name.
+// The queue name is assigned in the Constants.h file.
+-(NSString*)findQueueUrl
+{
+ @try {
+ NSString *queueNameToFind = [NSString stringWithFormat:@"/%@", QUEUE_NAME];
+
+ SQSListQueuesRequest *request = [[[SQSListQueuesRequest alloc] init] autorelease];
+ SQSListQueuesResponse *queuesResponse = [sqsClient listQueues:request];
+
+ for ( NSString *qUrl in queuesResponse.queueUrls ) {
+ if ( [qUrl hasSuffix:queueNameToFind] ) {
+ return qUrl;
+ }
+ }
+
+ return nil;
+ }
+ @catch ( NSException *exception ) {
+ NSLog( @"Exception : %@", exception );
+ return nil;
+ }
+}
+
+-(void)dealloc
+{
+ [topicARN release];
+ [queueUrl release];
+ [sqsClient release];
+ [snsClient release];
+ [super dealloc];
+}
+
+@end
View
30 samples/MessageBoard/MessageBoard/MessageQueueController.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import <UIKit/UIKit.h>
+
+
+// View used to display the messages in the queue.
+@interface MessageQueueController : UIViewController {
+ IBOutlet UITableView *messageTable;
+}
+
+@property (nonatomic, retain) NSMutableArray *messages;
+
+-(IBAction)back:(id)sender;
+
+-(NSString*)extractMessageFromJson:(NSString*)json;
+
+@end
View
118 samples/MessageBoard/MessageBoard/MessageQueueController.m
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#import "MessageQueueController.h"
+#import "MessageBoard.h"
+
+// View used to display the messages in the queue.
+@implementation MessageQueueController
+
+@synthesize messages;
+
+
+- (id)init
+{
+ self.messages = [[MessageBoard instance] getMessagesFromQueue];
+ return [super initWithNibName:@"MessageQueueController" bundle:nil];
+}
+
+-(IBAction)back:(id)sender
+{
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 1;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return [self.messages count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ // Configure the cell...
+ SQSMessage *message = [self.messages objectAtIndex:indexPath.row];
+ if ( message != nil && message.body != nil ){
+ cell.textLabel.text = [self extractMessageFromJson:message.body];
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ }
+
+ return cell;
+}
+
+-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+ SQSMessage *message = [self.messages objectAtIndex:indexPath.row];
+
+ [[MessageBoard instance] deleteMessageFromQueue:message];
+ [self.messages removeObjectAtIndex:indexPath.row];
+
+ NSArray *indexPaths = [NSArray arrayWithObjects:indexPath, nil];
+ [tableView beginUpdates];
+ [tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
+ [tableView endUpdates];
+ }
+}
+
+//-------------------------------------------
+// Better to use an actual JSON Parser here.
+//-------------------------------------------
+-(NSString*)extractMessageFromJson:(NSString*)json
+{
+ @try {
+ NSRange startIndex = [json rangeOfString:@"\"Message\""];
+ if ( startIndex.length != 0 ) {
+ NSRange startIndexRange = { startIndex.location, [json length] - startIndex.location };
+
+ NSRange colonIndex = [json rangeOfString:@":" options:NSLiteralSearch range:startIndexRange];
+ NSRange colonIndexRange = { colonIndex.location, [json length] - colonIndex.location };
+
+ NSRange startQuoteIndex = [json rangeOfString:@"\"" options:NSLiteralSearch range:colonIndexRange];
+ NSRange startQuoteRange = { startQuoteIndex.location + 1, [json length] - startQuoteIndex.location - 1 };
+
+ NSRange endQuoteIndex = [json rangeOfString:@"\"" options:NSLiteralSearch range:startQuoteRange];
+
+ NSRange elementRange = { startQuoteIndex.location + 1, endQuoteIndex.location - startQuoteIndex.location - 1 };
+
+ return [json substringWithRange:elementRange];
+ }
+ else {
+ return nil;
+ }
+ }
+ @catch ( NSException *exception ) {
+ return nil;
+ }
+}
+
+- (void)dealloc
+{
+ [messages release];
+ [super dealloc];
+}
+
+@end
View
294 samples/MessageBoard/MessageBoard/MessageQueueController.xib
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1306</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">301</string>
+ </object>
+ <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>IBUINavigationItem</string>
+ <string>IBUITableView</string>
+ <string>IBUIBarButtonItem</string>
+ <string>IBUIView</string>
+ <string>IBUINavigationBar</string>
+ <string>IBProxyObject</string>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUITableView" id="239904178">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 44}, {320, 416}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUISeparatorStyle">1</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">22</float>
+ <float key="IBUISectionFooterHeight">22</float>
+ </object>
+ <object class="IBUINavigationBar" id="378721039">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">290</int>
+ <string key="NSFrameSize">{320, 44}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSArray" key="IBUIItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUINavigationItem" id="205083303">
+ <reference key="IBUINavigationBar" ref="378721039"/>
+ <string key="IBUITitle">Message Queue</string>
+ <object class="IBUIBarButtonItem" key="IBUILeftBarButtonItem" id="959429911">
+ <string key="IBUITitle">Back</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUINavigationItem" ref="205083303"/>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrame">{{0, 20}, {320, 460}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">messageTable</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="239904178"/>
+ </object>
+ <int key="connectionID">8</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">back:</string>
+ <reference key="source" ref="959429911"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">9</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">