Jak przesłać UIImage do S3 z AWS iOS SDK v2
Strona README w Github ( https://github.com/aws/aws-sdk-ios-v2 ) ma już przykład przesłania obrazu, z adresu URL ścieżki pliku:
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = yourBucket;
uploadRequest.key = yourKey;
uploadRequest.body = yourDataURL; // <<<< this is a NSURL
uploadRequest.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize];
Ale co jeśli mam tylko UIImage
w pamięci (bez ścieżki do pliku)?
Czy można wgrać UIImage
(lub jest to NSData
) do S3
używając SDK
?
Czy byłoby łatwiej ręcznie używać HTTP API (używając czegoś w rodzaju AFNetworking)?
6 answers
Nawet jeśli AWSiOSSDKv2 nie obsługuje przesyłania obrazów z pamięci, możesz zapisać je jako plik, a następnie przesłać.
//image you want to upload
UIImage* imageToUpload = [UIImage imageNamed:@"imagetoupload"];
//convert uiimage to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", dateKey]];
[UIImagePNGRepresentation(imageToUpload) writeToFile:filePath atomically:YES];
NSURL* fileUrl = [NSURL fileURLWithPath:filePath];
//upload the image
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = fileUrl;
uploadRequest.bucket = AWS_BUCKET_NAME;
uploadRequest.key = @"yourkey";
uploadRequest.contentType = @"image/png";
[[transferManager upload:thumbNailUploadRequest] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
if(task.error == nil) {
NSLog(@"woot");
}
return nil;
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-24 08:16:25
Wygląda na to, że AWSiOSSDKv2 nie ma w tej chwili wsparcia dla wgrywania obrazków z pamięci : (
From a Github issue :
Decyzja o przyjęciu tylko Pliku Nsurl była podyktowana następującymi czynniki:
- od wersji v1 funkcje pauzy / wznowienia wymagają, aby dane wejściowe były pliki. Nie jest możliwe odzyskanie NSData i ponowna próba transferu, gdy aplikacja nie działa.
- transfer w tle tylko na iOS 7 i nowszych obsługuje pliki. Obecnie nie obsługujemy transferu w tle, ale planujemy go wspierać w przyszłości. Rozważaliśmy przyjęcie NSData i wewnętrznie utrzymywanie danych w katalogu tymczasowym.
- zdecydowaliśmy się nie włączać tego w wydaniu 2.0, ponieważ jeśli nsdata jest wspierany przez plik, podwaja zużycie dysku dla danych. Również, programiści mają do czynienia z błędami związanymi z dyskami podczas korzystania S3TransferManager. Mimo, że zdecydowaliśmy się nie akceptować NSData w 2.0 uwolnij, my jesteśmy otwarci na Wasze opinie. Jeśli jest to funkcja, którą chcesz aby zobaczyć w przyszłym wydaniu, utwórz nowy numer z żądanie funkcji.
```
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-18 22:39:03
Możesz najwyraźniej zrobić to za pomocą "presigned Url"
- (void)uploadImageToS3: (UIImage *)image {
NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = @"bucket-name";
getPreSignedURLRequest.key = @"image-name.jpg";
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
NSString *fileContentTypeString = @"text/plain";
getPreSignedURLRequest.contentType = fileContentTypeString;
[[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder] getPreSignedURL:getPreSignedURLRequest] continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(@"Error: %@", task.error);
} else {
NSURL *presignedURL = task.result;
NSLog(@"upload presignedURL is \n%@", presignedURL);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPMethod:@"PUT"];
[request setValue:fileContentTypeString forHTTPHeaderField:@"Content-Type"];
NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Upload errer: %@", error);
}
NSLog(@"Done");
}];
[uploadTask resume];
}
return nil;
}];
}
Udokumentowane w S3 docs for V2 SDK w http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html#use-pre-signed-urls-to-transfer-objects-in-the-background
To trochę bałagan z zagnieżdżonymi blokami końcowymi, ale gist polega na tym, że żądasz adresu url, a gdy to powróci, rozpoczynasz zadanie przesyłania. To był test prototypu, a nie dopracowany kod. Należy sprawdzić kod statusu na upload zamiast tylko błędu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-28 19:08:29
To jest zaktualizowana odpowiedź, więc ludzie nie muszą sami (tak jak ja): d
Importuj odpowiednie pliki (Pobierz tutaj)
#import <AWSCore/AWSCore.h>
#import <AWSS3TransferManager.h>
.m
- (void)viewDidLoad {
[super viewDidLoad];
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityPoolId:@"us-east-1:*******-******-*****-*****-*****"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
}
Użyłem przycisku, aby wiedzieć, kiedy użytkownik chce przesłać plik
- (void)upload{
//convert uiimage to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@".png"]];
[UIImagePNGRepresentation(YOUR_UIIMAGE) writeToFile:filePath atomically:YES];
NSURL* fileUrl = [NSURL fileURLWithPath:filePath];
//upload the image
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = fileUrl;
uploadRequest.bucket = @"YOUR_BUCKET_NAME";
uploadRequest.key = @"YOUR_FOLDER_NAME (if you have one)/NEW_IMAGE_NAME.png";
uploadRequest.contentType = @"image/png";
uploadRequest.ACL = AWSS3BucketCannedACLPublicRead;
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task) {
if (task.error != nil) {
NSLog(@"%s %@","Error uploading :", uploadRequest.key);
}else { NSLog(@"Upload completed"); }
return nil;
}];
}
Helpfull links:
Mam nadzieję, że to komuś pomoże!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-10 06:32:20
Cześć możesz piaskować obraz bez zapisywania obrazu w folderze tymczasowym w iPhonie Amazon iOS v2 daje taką opcję.
W tym kodzie logFile.body
jest to NSData
.
AWSS3PutObjectRequest *logFile = [AWSS3PutObjectRequest new];
logFile.bucket = uploadTokenData_.bucket;
logFile.key = key;
logFile.contentType = contentType;
logFile.body = data_;
logFile.contentLength = [NSNumber numberWithInteger:[data_ length]];
AWSS3 *S3 = [[AWSS3 alloc] initWithConfiguration:[AWSCredentialsProvider runServiceWithStsCredential]];
AWSS3TransferManager *transferManager = [[AWSS3TransferManager alloc] initWithS3:S3];
[[transferManager.s3 putObject:logFile] continueWithBlock:^id(BFTask *task)
{
NSLog(@"Error : %@", task.error);
if (task.error == nil)
{
NSLog(@"Uploadet");
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 11:02:07
W bieżącej wersji SDK możesz użyć AWSS3TransferUtility
, a następnie zrobi wszystko za Ciebie.
func uploadData() {
let data: Data = Data() // Data to be uploaded
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = {(task, progress) in
DispatchQueue.main.async(execute: {
// Do something e.g. Update a progress bar.
})
}
var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
// Do something e.g. Alert a user for transfer completion.
// On failed uploads, `error` contains the error object.
})
}
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadData(data,
bucket: "YourBucket",
key: "YourFileName",
contentType: "text/plain",
expression: expression,
completionHandler: completionHandler).continueWith {
(task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
// Do something with uploadTask.
}
return nil;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-04 09:46:15