IOS AWS s3 bucket image uploading problems - ios

Been trying to get this to work for a while know i have tried it with data and with streaming but with no luck, I assume i do not need to create the bucket as shown in most examples as the bucket i want to upload to already exists, also it tells me the bucket i am trying to access, however when i try to upload i get this
"Error uploading image to S3: The XML you provided was not well-formed or did not validate against our published schema"
here is the code
UIImage * img = [[[[CurrentGamesInfo sharedCurrentGamesInfo]GameInCreation] GetImageToSend]_imageToSend];
NSData *savedImageData = UIImageJPEGRepresentation(img, 0.8);
NSString *pictureName = [[[CurrentGamesInfo sharedCurrentGamesInfo]GameInCreation] GetGameID];
#try
{
AmazonS3Client *s3 = [[[AmazonS3Client alloc] initWithAccessKey:MY_ACCESS_KEY_ID withSecretKey:MY_SECRET_KEY] autorelease];
//[s3 createBucket:[[[S3CreateBucketRequest alloc] initWithName:MY_PICTURE_BUCKET] autorelease]];
NSArray *bucketArray = [s3 listBuckets];
S3Bucket *bucket = [[s3 listBuckets] objectAtIndex:0];
NSLog(#"%#",[bucket name]);
S3PutObjectRequest *por = [[[S3PutObjectRequest alloc] initWithKey:pictureName inBucket:MY_PICTURE_BUCKET] autorelease];
por.contentType = #"image/jpeg";
//por.data = savedImageData;
//por.cannedACL = [S3CannedACL publicRead];
S3UploadInputStream *stream = [S3UploadInputStream inputStreamWithData:savedImageData];
//stream.delay = 0.2;
//stream.packetSize = 16;
por.contentLength = [savedImageData length];
por.stream = stream;
[s3 putObject:por];
}
#catch (AmazonClientException *exception)
{
NSLog(#"Error uploading image to S3: %#", exception.message);
}
sooooo...what am i doing wrong?

Nevermind...the variable "pictureName" was nil...I slink away in shame

Related

AWSS3GetObjectRequest ifModifiedSince not working

Building for iOS 7+ ,
Building on Xcode 6.1 ,
Using Amazon SDK AWSiOSSDKv2 2.0.12 ,
Testing on iPhone 5s and iPad 2
I am downloading images from my Amazon S3 bucket with the Amazon SDK for iOS.
The downloading is working fine but I want to use the ifModifiedSince property to retrieve only images that have been modified since a certain date
(see http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSS3GetObjectRequest.html#//api/name/ifModifiedSince )
However, this is not working. Even when I specify a ifModifiedSince date that is LATER THAN the modified date of the file on S3, the file is returned.
According to the Amazon documentation:
ifModifiedSince -
Return the object only if it has been modified since the specified
time, otherwise return a 304 (not modified).
So I am not sure if I am doing something wrong or Amazon has a bug in the SDK.
Here is my code:
-(void)downloadPhotoWithName:(NSString*)name completed:(retrievedImage)completed {
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *cachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [cachePaths firstObject];
NSString *filename = [NSString stringWithFormat:#"%#.jpg", name];
NSString *filePath = [cacheDirectory stringByAppendingPathComponent:filename];
AWSS3 *transferManager = [AWSS3 defaultS3];
AWSS3GetObjectRequest *profilePhoto = [[AWSS3GetObjectRequest alloc] init];
profilePhoto.bucket = S3BUCKETNAMEIMAGE;
profilePhoto.key = filename;
if ([manager fileExistsAtPath:filePath isDirectory:NULL]) {
NSDictionary *att = [manager attributesOfItemAtPath:filePath error:nil];
if (att) {
//Get the date of when the file was modified so we can request to retrieve
//the file only if it was modified SINCE that date
NSDate *modifiedDate = [att objectForKey:NSFileModificationDate];
if (modifiedDate) {
profilePhoto.ifModifiedSince = modifiedDate;
}
}
}
[[transferManager getObject:profilePhoto] continueWithBlock:^id(BFTask *task) {
//If it was working we should get a 304 not the image file
if (task.result) {
AWSS3GetObjectOutput *output = (AWSS3GetObjectOutput*)task.result;
NSData *imageData = (NSData*)output.body;
if (imageData) {
NSDictionary* attr = [NSDictionary dictionaryWithObjectsAndKeys:output.lastModified, NSFileModificationDate, NULL];
//The log confirms that the date I am passing for ifModifiedSince is LATER THAN
//the last modified date of the file on S3
//but the the image file is returned anyway.. is it a problem with Amazon ?
NSLog(#"output.lastModified: %#\nmodifiedDate: %#", output.lastModified, profilePhoto.ifModifiedSince);
if ([manager createFileAtPath:filePath contents:imageData attributes:attr]) {
completed(imageData);
}
else {
NSLog(#"Could not save image to disk for some reason");
completed(nil);
}
}
else {
completed(nil);
}
}
else if (task.error) {
NSLog(#"DownloadPhotoError: %#", task.error);
completed(nil);
}
return nil;
}];
}
We've released the AWS Mobile SDK for iOS 2.0.14. It should address the time formatting issue.

Box: Getting sharedlink parameter immediately after uploading new file

Is there any way to get sharedLink parameter, immediately after uploading a new file on box in BoxFile block.
I've tried following code, but it's returning sharedlink parameter as nil.
BoxFilesRequestBuilder *builder = [[BoxFilesRequestBuilder alloc] init];
builder.name = imageName;
builder.parentID = folderID;
//--- shared link object ---//
BoxSharedObjectBuilder *sharedBuilder = [[BoxSharedObjectBuilder alloc] init];
sharedBuilder.access = BoxAPISharedObjectAccessOpen;
builder.sharedLink = sharedBuilder;
NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:imagePath];
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:imagePath error:nil];
long long contentLength = [[fileAttributes objectForKey:NSFileSize] longLongValue];
[[BoxSDK sharedSDK].filesManager uploadFileWithInputStream:inputStream contentLength:contentLength MIMEType:nil requestBuilder:builder success:fileBlock failure:failureBlock progress:nil];
You have to make a second call after the file is uploaded.

how to upload image to asw s3

I am uploading image from the following code -
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
AmazonS3Client *s3Client = [[[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY] autorelease];
s3Client.timeout = 240;
NSString *bucketName = [NSString stringWithFormat:#"test/images/"];
NSString *imageName = [NSString stringWithFormat:#"testimage.jpg"];
S3PutObjectRequest *objReq = [[S3PutObjectRequest alloc] initWithKey:imageName inBucket:bucketName];
objReq.contentType = #"image/jpeg";
objReq.data = imageData;
objReq.delegate = self;
objReq.contentLength = [imageData length];
[s3Client putObject:objReq];
I am getting following error -
S3Response.m|-[S3Response connection:didFailWithError:]|234|UserInfo.NSUnderlyingError = Error Domain=kCFErrorDomainCFNetwork Code=-1003 "A server with the specified hostname could not be found." UserInfo=0xac62aa0 {NSErrorFailingURLKey=https://test/images/.s3.amazonaws.com/testimage.jpg
Please suggest me what i am doing wrong.
in bucketName you are storing the path to the folder within your bucket. You need to only have your bucket name there.
It should be:
https://bucketname.s3.amazonaws.com/test/images/testimage.jpg
Your's is:
https://test/images/.s3.amazonaws.com/testimage.jpg
See the problem? test/images/.s3.amazonaws.com is not a valid domain name.

Multipart Upload to Amazon S3 with IOS 6

Trying to upload files bigger than 5 mb to Amazon S3
http://aws.amazon.com/articles/0006282245644577, here it is stated that
// The S3UploadInputStream was deprecated after the release of iOS6
Files under 5 mb I can easily upload over wifi with:
NSData *dataForAamzon = [[NSFileManager defaultManager] contentsAtPath:pathForFiile];
#try {
NSString *uploadName= #"somestring";
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:uploadName
inBucket:[Constants userEventBucket]];
por.contentType = nil;
por.data = dataForAamzon;
// Put the image data into the specified s3 bucket and object.
S3PutObjectResponse *putObjectResponse = [self.s3 putObject:por];
[self performSelector:#selector(uploadAllFilesToAmazon:error:) withObject:nil withObject:putObjectResponse.error];
}
#catch ( AmazonServiceException *exception ) {
NSLog( #"Upload Failed, Reason: %#", exception );
}
Since S3UploadInputStream *stream was deprecated , how can I check if file is bigger than 5mb and use multipart upload in IOS 6 or later versions.
Thanks,
I hope you need to check the size of a local file exceeds 5MB right ?
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:_client.filename error:nil];
if(fileAttributes)
{
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long totalFileSize = [fileSizeNumber longLongValue];
if(totalFileSize > 5*1024*1024)
// Go for multipart upload
else
// Go for Direct Put request
}
Or from the NSData you can take the Length and perform the same calculation.
New release of AWS SDK solved my problem.
New AWS SDK is handling files size automatically you need to create trasnfer manager variable and delegate it to s3 object
something like
-(void) uploadAgendatoAmazon
{
//pass string in memory to nsdictionary
NSData * data = [_uploadPlistString dataUsingEncoding:NSUTF8StringEncoding];
NSString *uploadName= [NSString stringWithFormat:#"%#/%#/agenda.plist",[[NSUserDefaults standardUserDefaults] valueForKey:#"email"],self.textEventName.text];
self.s3.maxRetries = 10;
self.s3.timeout = 60;
self.tm = [S3TransferManager new];
self.tm.s3 = self.s3;
self.tm.operationQueue.maxConcurrentOperationCount = 2;
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:uploadName
inBucket:[Constants userEventBucket]];
por.contentType = nil;
por.data = data;
por.delegate = self;
por.requestTag = #"uploadAgendatoAmazon";
// Put the image data into the specified s3 bucket and object.
[self.tm upload:por];
}
Here is the blog post for full details;
http://mobile.awsblog.com/post/TxIRFEQTW9XU8G/S3TransferManager-for-iOS-Part-I-Asynchronous-Uploads

Email attachment sent using SKPSMTPMessage appears in iOS mail client as contact

I have tested the code for sending attachments using this useful library:
Skpsmtpmessage library
The email seems to get sent correctly, and when I view it through hotmail or gmail clients I see the jpeg image. However, when I view this same email through an iOS mail client, the attachment appears as a "contact" and clicking on this gives me the option to save the file as a new contact.
I have tried sending an email with jpeg attachment from hotmail, and when I do this it appears correctly in the iOS client.
Does anyone know whether this is the code or iOS getting it wrong?
//the guts of the message.
SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
testMsg.fromEmail = #"aname#gmail.com";
testMsg.toEmail = #"aname#gmail.com";
testMsg.relayHost = #"smtp.gmail.com";
testMsg.requiresAuth = YES;
testMsg.login = #"aname#gmail.com";
testMsg.pass = #"password";
testMsg.subject = #"The message subject";
testMsg.wantsSecure = YES; // smtp.gmail.com doesn't work without TLS!
// Only do this for self-signed certs!
// testMsg.validateSSLChain = NO;
testMsg.delegate = self;
//email contents
NSDate* now = [NSDate date];
NSString * bodyMessage = [NSString stringWithFormat:#"The message body"];
// email image if it exists
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/file.jpeg"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray* parts = [[NSMutableArray alloc] init];
// add plain part
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
bodyMessage ,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
[parts addObject: plainPart];
// add attachments
NSData *attachmentData = [NSData dataWithContentsOfFile:jpgPath];
NSString *directory = #"text/directory;\r\n\tx-unix-mode=0644;\r\n\tname=\"file.jpeg\"";
NSString *attachment = #"attachment;\r\n\tfilename=\"file.jpeg\"";
NSDictionary *image_part = [NSDictionary dictionaryWithObjectsAndKeys:
directory,kSKPSMTPPartContentTypeKey,
attachment,kSKPSMTPPartContentDispositionKey,
[attachmentData encodeBase64ForData],kSKPSMTPPartMessageKey,
#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
[parts addObject: image_part];
testMsg.parts = parts;
[testMsg send];
Try to change
NSString *directory = #"text/directory;...
to
NSString *directory = #"text/jpeg;...
I hope this works for you!
Steffen

Resources