Skip to content
Browse files

Initial import

  • Loading branch information...
0 parents commit 414de062758e3da7e24761410feecea633d3722e @mattt mattt committed
Showing with 456 additions and 0 deletions.
  1. +145 −0 AFAmazonS3Client.h
  2. +259 −0 AFAmazonS3Client.m
  3. +19 −0 LICENSE
  4. +33 −0 README.md
145 AFAmazonS3Client.h
@@ -0,0 +1,145 @@
+//
+// AFAmazonS3Client.h
+//
+// Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "AFHTTPClient.h"
+
+extern NSString * const kAFAmazonS3BaseURLString;
+
+@interface AFAmazonS3Client : AFHTTPClient
+
+/**
+
+ */
+@property (nonatomic, retain) NSURL *baseURL;
+
+/**
+
+ */
+@property (nonatomic, copy) NSString *bucket;
+
+/**
+
+ */
+- (id)initWithAccessKeyID:(NSString *)accessKey
+ secret:(NSString *)secret;
+
+/**
+
+ */
+- (void)enqueueS3RequestOperationWithMethod:(NSString *)method
+ path:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+///-------------------------
+/// @name Service Operations
+///-------------------------
+
+/**
+ Returns a list of all buckets owned by the authenticated request sender.
+ */
+- (void)getServiceWithSuccess:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+
+///------------------------
+/// @name Bucket Operations
+///------------------------
+
+/**
+ Lists information about the objects in a bucket for a user that has read access to the bucket.
+ */
+- (void)getBucket:(NSString *)bucket
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Creates a new bucket belonging to the account of the authenticated request sender. Optionally, you can specify a EU (Ireland) or US-West (N. California) location constraint.
+ */
+- (void)putBucket:(NSString *)bucket
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Deletes the specified bucket. All objects in the bucket must be deleted before the bucket itself can be deleted.
+ */
+- (void)deleteBucket:(NSString *)bucket
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+///----------------------------------------------
+/// @name Object Operations
+///----------------------------------------------
+
+/**
+ Retrieves information about an object for a user with read access without fetching the object.
+ */
+- (void)headObjectWithPath:(NSString *)path
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Gets an object for a user that has read access to the object.
+ */
+- (void)getObjectWithPath:(NSString *)path
+ progress:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))progress
+ success:(void (^)(id responseObject, NSData *responseData))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Gets an object for a user that has read access to the object.
+ */
+- (void)getObjectWithPath:(NSString *)path
+ outputStream:(NSOutputStream *)outputStream
+ progress:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Adds an object to a bucket using forms.
+ */
+- (void)postObjectWithFile:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Adds an object to a bucket for a user that has write access to the bucket. A success response indicates the object was successfully stored; if the object already exists, it will be overwritten.
+ */
+- (void)putObjectWithFile:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+/**
+ Deletes the specified object. Once deleted, there is no method to restore or undelete an object.
+ */
+- (void)deleteObjectWithPath:(NSString *)path
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+
+@end
259 AFAmazonS3Client.m
@@ -0,0 +1,259 @@
+//
+// AFAmazonS3Client.m
+//
+// Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "AFAmazonS3Client.h"
+#import "AFXMLRequestOperation.h"
+
+NSString * const kAFAmazonS3BaseURLString = @"http://s3.amazonaws.com";
+NSString * const kAFAmazonS3BucketBaseURLFormatString = @"http://%@.s3.amazonaws.com";
+
+#pragma mark -
+
+@interface AFAmazonS3Client ()
+@property (readwrite, nonatomic, copy) NSString *accessKey;
+@property (readwrite, nonatomic, copy) NSString *secret;
+
+- (void)setObjectWithMethod:(NSString *)method
+ file:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progressBlock
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure;
+@end
+
+@implementation AFAmazonS3Client
+@synthesize baseURL = _s3_baseURL;
+@synthesize bucket = _bucket;
+@synthesize accessKey = _accessKey;
+@synthesize secret = _secret;
+
+- (id)initWithBaseURL:(NSURL *)url {
+ self = [super initWithBaseURL:url];
+ if (!self) {
+ return nil;
+ }
+
+ [self registerHTTPOperationClass:[AFXMLRequestOperation class]];
+
+ return self;
+}
+
+- (id)initWithAccessKeyID:(NSString *)accessKey
+ secret:(NSString *)secret
+{
+ self = [self initWithBaseURL:[NSURL URLWithString:kAFAmazonS3BaseURLString]];
+ if (!self) {
+ return nil;
+ }
+
+ self.accessKey = accessKey;
+ self.secret = secret;
+
+ return self;
+}
+
+- (NSURL *)baseURL {
+ if (!_s3_baseURL && self.bucket) {
+ return [NSString stringWithFormat:kAFAmazonS3BucketBaseURLFormatString, self.bucket];
+ }
+
+ return _s3_baseURL;
+}
+
+- (void)setBucket:(NSString *)bucket {
+ [self willChangeValueForKey:@"baseURL"];
+ [self willChangeValueForKey:@"bucket"];
+ _bucket = bucket;
+ [self didChangeValueForKey:@"bucket"];
+ [self didChangeValueForKey:@"baseURL"];
+}
+
+#pragma mark -
+
+- (void)enqueueS3RequestOperationWithMethod:(NSString *)method
+ path:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ NSURLRequest *request = [self requestWithMethod:method path:path parameters:parameters];
+ AFHTTPRequestOperation *requestOperation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
+ if (success) {
+ success(responseObject);
+ }
+ } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
+ if (failure) {
+ failure(error);
+ }
+ }];
+
+ [self enqueueHTTPRequestOperation:requestOperation];
+}
+
+#pragma mark - Service Operations
+
+- (void)getServiceWithSuccess:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"GET" path:@"/" parameters:nil success:success failure:failure];
+}
+
+#pragma mark - Bucket Operations
+
+- (void)getBucket:(NSString *)bucket
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"GET" path:bucket parameters:nil success:success failure:failure];
+}
+
+- (void)putBucket:(NSString *)bucket
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"PUT" path:bucket parameters:parameters success:success failure:failure];
+
+}
+
+- (void)deleteBucket:(NSString *)bucket
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"DELETE" path:bucket parameters:nil success:success failure:failure];
+}
+
+#pragma mark - Object Operations
+
+- (void)headObjectWithPath:(NSString *)path
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"HEAD" path:path parameters:nil success:success failure:failure];
+}
+
+- (void)getObjectWithPath:(NSString *)path
+ progress:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))progress
+ success:(void (^)(id responseObject, NSData *responseData))success
+ failure:(void (^)(NSError *error))failure
+{
+ NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:nil];
+ AFHTTPRequestOperation *requestOperation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
+ if (success) {
+ success(responseObject, operation.responseData);
+ }
+ } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
+ if (failure) {
+ failure(error);
+ }
+ }];
+
+ [requestOperation setUploadProgressBlock:progress];
+
+ [self enqueueHTTPRequestOperation:requestOperation];
+}
+
+- (void)getObjectWithPath:(NSString *)path
+ outputStream:(NSOutputStream *)outputStream
+ progress:(void (^)(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:nil];
+ AFHTTPRequestOperation *requestOperation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
+ if (success) {
+ success(responseObject);
+ }
+ } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
+ if (failure) {
+ failure(error);
+ }
+ }];
+
+ [requestOperation setUploadProgressBlock:progress];
+ [requestOperation setOutputStream:outputStream];
+
+ [self enqueueHTTPRequestOperation:requestOperation];
+}
+
+- (void)postObjectWithFile:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self setObjectWithMethod:@"POST" file:path parameters:parameters progress:progress success:success failure:failure];
+}
+
+- (void)putObjectWithFile:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self setObjectWithMethod:@"PUT" file:path parameters:parameters progress:progress success:success failure:failure];
+}
+
+- (void)deleteObjectWithPath:(NSString *)path
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ [self enqueueS3RequestOperationWithMethod:@"DELETE" path:path parameters:nil success:success failure:failure];
+}
+
+- (void)setObjectWithMethod:(NSString *)method
+ file:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ progress:(void (^)(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
+ success:(void (^)(id responseObject))success
+ failure:(void (^)(NSError *error))failure
+{
+ NSMutableURLRequest *fileRequest = [NSMutableURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
+ [fileRequest setCachePolicy:NSURLCacheStorageNotAllowed];
+
+ NSURLResponse *response = nil;
+ NSError *error = nil;
+ NSData *data = [NSURLConnection sendSynchronousRequest:fileRequest returningResponse:&response error:&error];
+
+ if (data && response) {
+ NSMutableURLRequest *request = [self multipartFormRequestWithMethod:path path:@"/" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
+ [formData appendPartWithFileData:data name:@"file" fileName:[path lastPathComponent] mimeType:[response MIMEType]];
+ }];
+
+ AFHTTPRequestOperation *requestOperation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
+ if (success) {
+ success(responseObject);
+ }
+ } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
+ if (failure) {
+ failure(error);
+ }
+ }];
+
+ [requestOperation setUploadProgressBlock:progress];
+
+ [self enqueueHTTPRequestOperation:requestOperation];
+ }
+}
+
+@end
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Mattt Thompson (http://mattt.me/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
33 README.md
@@ -0,0 +1,33 @@
+# AFAmazonS3Client
+
+`AFAmazonS3Client` is an `AFHTTPClient` subclass for interacting with the [Amazon S3 API](http://aws.amazon.com/s3/).
+
+As the S3 API returns XML responses, you may find it useful to include [AFKissXMLRequestOperation](https://github.com/AFNetworking/AFKissXMLRequestOperation) (just remember to do `-registerHTTPOperationClass:`)
+
+**Caution:** This code is still in its early stages of development, so exercise caution when incorporating this into production code.
+
+## Example Usage
+
+```objective-c
+AFAmazonS3Client *s3Client = [[AFAmazonS3Client alloc] initWithAccessKeyID:@"..." secret:@"..."];
+ s3Client.bucket = @"my-bucket-name";
+ [s3Client postObjectWithFile:@"/path/to/file" parameters:nil progress:^(NSInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
+ NSLog(@"%f%% Uploaded", (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100));
+ } success:^(id responseObject) {
+ NSLog(@"Upload Complete");
+ } failure:^(NSError *error) {
+ NSLog(@"Error: %@", error);
+ }];
+```
+
+## Contact
+
+Mattt Thompson
+
+- http://github.com/mattt
+- http://twitter.com/mattt
+- m@mattt.me
+
+## License
+
+AFAmazonS3Client is available under the MIT license. See the LICENSE file for more info.

0 comments on commit 414de06

Please sign in to comment.
Something went wrong with that request. Please try again.