I looked at the docs and i don't see support for elastic transcoding sdk for ios.
My use case is to move the file "videoFile.mp4" from "bucket1" in mp4 format to transcode and create the file "videoFile.webm" again back to "bucket1".
How can i use amazon sdk(code sample) to make the rest calls to do this task?
UPDATE:
I am able to get something going but i am having another issue.
But i am getting this message when I am making the call to https://elastictranscoder.us-west-2.amazonaws.com/2014-06-16/jobs
<InvalidSignatureException>
<Message>Credential should be scoped to correct service: 'elastictranscoder'. </Message>
</InvalidSignatureException>
The code below is what i have tried.
AmazonCredentials *credentials = [[AmazonCredentials alloc] init];
credentials.secretKey = SECRET_KEY;
credentials.accessKey = ACCESS_KEY_ID;
NSMutableDictionary *parameter = [NSMutableDictionary dictionaryWithObjectsAndKeys:
// dateString1, #"x-amz-date",
#"elastictranscoder.us-west-2.amazonaws.com:443",#"host",
#"application/x-amz-json-1.0", #"content-type",
length, #"content-length",
nil];
AmazonServiceRequest *request = [[AmazonServiceRequest alloc] init];
request.urlRequest.HTTPMethod = #"POST";
request.regionName = #"us-west-2";
request.serviceName = #"ets";
NSLog(#"***********************************************************************************************");
NSLog(#"***********************************************************************************************");
[AmazonAuthUtils signRequestV4:request headers:parameter payload:jsonStringData credentials:credentials];
NSLog(#"***********************************************************************************************");
NSLog(#"***********************************************************************************************");
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc]
initWithURL:[NSURL
URLWithString:#"https://elastictranscoder.us-west-2.amazonaws.com"]];
[mutableRequest setHTTPMethod:#"POST"];
for(id key in parameter){
[mutableRequest setValue:[parameter objectForKey:key] forHTTPHeaderField:key];
}
NSLog([request.urlRequest valueForHTTPHeaderField:#"x-amz-date"]);
NSLog([request.urlRequest valueForHTTPHeaderField:#"Authorization"]);
// add the Authorization signature and the date
[mutableRequest setValue:[request.urlRequest valueForHTTPHeaderField:#"x-amz-date"] forHTTPHeaderField:#"x-amz-date"];
[mutableRequest setValue:[request.urlRequest valueForHTTPHeaderField:#"Authorization"] forHTTPHeaderField:#"Authorization"];
[mutableRequest setHTTPBody:[jsonStringData dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:mutableRequest delegate:self];
In general, you should set up a pipeline from the AWS Management Console because it is a one-time setup. It does not make sense to create a pipeline from mobile devices. From mobile devices, you should just upload video files to your Amazon S3 bucket. A backend server (e.g. Amazon EC2 and AWS Elastic Beanstalk are both good options) should monitor the bucket and create jobs for Elastic Transcoder. AWS just announced AWS Lambda, and you may want to check it. Once the job is done, you can use Amazon SNS to get notified.
Related
The documentation for AWS (Amazon Web Services) is vast, and rather chaotic. I found a git repo for iOS that demonstrates performing various tasks including a couple of projects for getting/putting data to S3.
I already have an existing client application that uses Apples NSURLSession to do HTTPS GET requests for content from S3 when the records are public. However, my client want the data to be secure.
I don't want to invest the time to learn the AWSS3TransferManager framework, and I don't want to include the whole framework in my project, either). I don't want all that baggage. All I need is a call that will let me provide a user ID or access key/secret key, or perhaps a password, and get a query string I can add to my HTTP get requests that authorizes the request for all users of the app.
I don't need upload. I don't need API-based console support. I don't need or want Amazon's session manager/download manager. All I want is the 1 call that will let me provide an access key and secret key and get back something I can add to the get request that authorizes it, so I can submit a request and get back a file. Should be easy, right? I've been pouring through the documentation and sample code for a couple of hours now, and no luck.
Looking at the samples, they use 500 kilos of frameworks I don't need and don't want.
Can somebody point me to a minimal library that lets me generate the key(s) I need to prove that the user has access to this content, given username and an access key Id and secret key, or perhaps a password? This would not be that hard.
Here is simple code for HTTP GET. If you are interested in HTTP PUT - check implementation at http://simpleios.s3-website-us-east-1.amazonaws.com.
#import <CommonCrypto/CommonCrypto.h>
static NSString * const accessKey=#"AKIAIOSFODNN7EXAMPLE";
static NSString * const secretKey=#"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
...
NSString * fileUrl=#"https://s3.amazonaws.com/someBucket/someFile";
NSString * bucket=#"someBucket";
NSString * filePath=#"someFile";
NSURLSession *delegateFreeSession=[NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration defaultSessionConfiguration] delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
[[delegateFreeSession dataTaskWithURL: [NSURL URLWithString:[fileUrl stringByAppendingString:[self buildQuery:bucket forFile:filePath]]] completionHandler:^(NSData *received, NSURLResponse *response, NSError *error) {
if(error!=nil ){
NSLog(#"Error trying to download file - %#", error);
}
else{
//do something
}
}] resume ];
...
- (NSString * ) buildQuery:(NSString *)bucketName forFile:(NSString *)filePath{
NSString *expDate=[self expirationDate];
NSMutableString *base=[NSMutableString new];
[base appendString:#"?AWSAccessKeyId="];
[base appendString:accessKey];
[base appendString:#"&Expires="];
[base appendString:expDate];
[base appendString:#"&Signature="];
NSMutableString *stringToSign=[NSMutableString new];
[stringToSign appendString:#"GET\n\n\n" ];
[stringToSign appendString:expDate];
[stringToSign appendString:#"\n" ];
[stringToSign appendString:#"/"];
[stringToSign appendString:bucketName];
[stringToSign appendString:#"/"];
[stringToSign appendString:filePath];
NSString *signature=[self sign:stringToSign];
signature=[signature stringByReplacingOccurrencesOfString:#"/" withString:#"%2F"];
signature=[signature stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
signature=[signature stringByReplacingOccurrencesOfString:#"=" withString:#"%3D"];
[base appendString:signature];
return base;
}
- (NSString *) expirationDate{
int expireInSeconds=300;
double sec=[[NSDate date] timeIntervalSince1970]+expireInSeconds;
static NSNumberFormatter *numberFormatter=nil;
if(numberFormatter==nil){
numberFormatter=[NSNumberFormatter new];
[numberFormatter setMaximumFractionDigits:0];
}
NSString *expDate=[numberFormatter stringFromNumber:[NSNumber numberWithDouble:sec]];
return expDate;
}
- (NSString *)sign:(NSString *)stringToSign {
NSData *data=[stringToSign dataUsingEncoding:NSUTF8StringEncoding];
CCHmacContext context;
const char *keyCString = [secretKey cStringUsingEncoding:NSASCIIStringEncoding];
CCHmacInit(&context, kCCHmacAlgSHA1, keyCString, strlen(keyCString));
CCHmacUpdate(&context, [data bytes], [data length]);
unsigned char digestRaw[CC_SHA1_DIGEST_LENGTH];
NSInteger digestLength = CC_SHA1_DIGEST_LENGTH;
CCHmacFinal(&context, digestRaw);
NSData *digestData = [NSData dataWithBytes:digestRaw length:digestLength];
return [digestData base64EncodedStringWithOptions:kNilOptions];
}
One problem with this is that it sounds like you are trying to embed secret/access keys into the app itself instead of using something more secure like Amazon Cognito https://aws.amazon.com/cognito/, which the iOS SDK provides access to.
The other is that iOS SDK for AWS doesn't allow you to cherry pick which methods to include, though it does allow you to generate a pre-signed URL for S3 gets. For just S3 you only need the S3 & Core frameworks, but it sounds like that is too much as well.
If you really just want the most minimal download size possible you could implement AWS signing yourself by looking at the AWS iOS SDK source code https://github.com/aws/aws-sdk-ios or S3's signing documentation, but signing an AWS request is non-trivial, and you would lose a lot of beneficial logic (retries, ect...).
You also mentioned not wanting to learn the TransferManager. The TransferUtility is the successor of that and would be drastically faster to learn than implementing your own signing. I can't see it taking more than an hour or two to understand it (maybe a little more if you decide to use Cognito for authentication, but that's really tangential to TransferUtility). http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transferutility.html
Edit: In order to give credentials for the PreSignedURLBuilder. You can also see adding credentials to all clients created with the SDK at http://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html (Getting started with Swift/Objective-c section)
You can use this to provide credentials
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
initWithRegionType:AWSRegionUSEast1 identityPoolId:#"IDENTITY_POOL_ID"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc]
initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSS3PreSignedURLBuilder registerS3PreSignedURLBuilderWithConfiguration:configuration
forKey:#"customServiceConfiguration"];
AWSS3PreSignedURLBuilder *customPreSignedURLBuilder = [AWSS3PreSignedURLBuilder S3PreSignedURLBuilderForKey:#"customServiceConfiguration"];
as of now I have it like so:
NSURLRequest *Request = [NSURLRequest requestWithURL:[NSURL URLWithString: reqURLStr]];
NSURLResponse *resp = nil;
NSError *error = nil;
NSData *response = [NSURLConnection sendSynchronousRequest: Request returningResponse: &resp error: &error];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
return responseString;
and I call it like so:
NSString *stripeCustomerRequestURL = [NSString stringWithFormat:#"https://api.stripe.com/v1/customers/%#",stripeCustomerId];
// NSString for the return of the tax in decimal form
NSString *customerInformation = [self retrieveStripeCustomer:stripeCustomerRequestURL];
I am getting this error which I know I need to pass the api key but how can I?
{
"error": {
"type": "invalid_request_error",
"message": "You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/."
}
}
It is not considered secure to be using your Stripe Secret API key from code that runs on a client device (iOS / Android apps, desktop apps, etc). As soon as you include your API key in a shipped binary, you can assume someone will inspect your binary and be able to extract the strings from it, including your API key thus compromising it.
Your API key should only be used on a server that you control. Your iOS app can call endpoints on your server and in turn your server will call out to Stripe.
Have problem accessing file using presigned url generated by aws sdk, given all necessary permission for the bucket.
I have downloaded the sample code from there github and changed the below
Awscredential provider as per my requirement.
The changes are below
AWSStaticCredentialsProvider *credentialsProvider =[[AWSStaticCredentialsProvider alloc] initWithAccessKey:S3AccessKey secretKey:S3secretKey];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
Even though i upload the file sucessfully to aws I am not able to access them using the presigned url which i get from the aws sdk while uploading.
Can anyone point out the things i am missing in order to access the files using presigned url.
when url is loaded in browser SignatureDoesNotMatch error is shown
The most possible reason for "SignatureDoesNotMatch" is the contents in header-field are different from the one provided while generating the presigned url.
Here is a code snippet to demonstrate how to generate and download a file by using presigned url:
AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = #"bucketname";
getPreSignedURLRequest.key = #"keyname";
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodGET;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
AWSS3PreSignedURLBuilder *preSignedURLBuilder = [AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder];
[[[preSignedURLBuilder getPreSignedURL:getPreSignedURLRequest] continueWithBlock:^id(BFTask *task) {
if (task.error) {
XCTAssertNil(task.error);
return nil;
}
NSURL *presignedURL = task.result;
//NSLog(#"(GET)presigned URL is: %#",presignedURL.absoluteString);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
NSError *returnError = nil;
NSHTTPURLResponse *returnResponse = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&returnResponse error:&returnError];
return nil;
}] waitUntilFinished];
The problem is with presigned url encoding. In iOS and android sdks (not in windows) you need to encode the query string in the Presigned url again.
NEWURL=baseurl +(encoded query String);
NEWURL is the correct url you can access.
it worked for me.
Try with this, you need to register PreSignedURL builder.
AWSStaticCredentialsProvider *credentialsProvider =[[AWSStaticCredentialsProvider alloc] initWithAccessKey:S3AccessKey secretKey:S3secretKey];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
// Register S3 PreSignedURL Builder
[AWSS3PreSignedURLBuilder registerS3PreSignedURLBuilderWithConfiguration:configuration forKey:#"configuration_name"];
AWSS3PreSignedURLBuilder * urlBuilder = [AWSS3PreSignedURLBuilder S3PreSignedURLBuilderForKey:#"configuration_name"];
Trying to understand how this all works. New to oauth and api integrations.
Not looking for a better way. Looking to understand and expand on what this is doing.
I followed this tutorial and have it working
through part 3.
I kind of understand, but having a hard time connecting the code to the Tumblr API documentation.
The tutorial leaves off with having the user's Access Token.
How do I use the Access Token to get the users info with api.tumblr.com/v2/user/info in xcode?
With this information I might be able to put together an understanding in my head.
Code example would be much appreciated!
#Ir100,
use the same acess_token and secret_key you generated via OAuth Library and just change your request url(API) because every time you have to send other parameter for API call.
_consumer = [[OAConsumer alloc] initWithKey: _consumerKey secret: _secretKey];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL: url consumer: _consumer token:token realm:nil signatureProvider: nil] ;
if (!request) return;
if (self.pin.length)
token.verifier = _pin;
[request setHTTPMethod: #"POST"];
if (_api)
[request setHTTPMethod: #"GET"];
NSMutableArray *params = [[NSMutableArray alloc] initWithArray:request.oa_parameters];
request.oa_parameters = params;
OADataFetcher *fetcher = [[OADataFetcher alloc] init] ;
[fetcher fetchDataWithRequest: request delegate: self didFinishSelector: success didFailSelector: fail];
I am currently developing an iOS application and am implementing the Box.Net SDK. I have gotten everything to work except the ability to move files around, which is not a native feature of the SDK. I am trying to twist my way through it.
If you are familiar with the structure of Box.Net, each file/folder has an ID number for itself, and an ID its parent. From what I understand if I want to move a file, I am supposed to change the parent ID number on the file which will point it to the new location. I can't seem to get it to work properly though. My application seems to keep crashing.
This is what I have so far, generalized.
BoxObject *boxObject = [[[Box objectWithID:(ID#ofParent)] children] objectAtIndex:i];
[boxObject parent].boxID = 0; // <-- Problem (causes crash)
I also tried this.
[boxObject setParent:[Box folderWithID:[BoxID numberWithInt:i]]];
The boxObject variable is the file that I want to move. I am setting its parent ID equal to 0, which is supposed to be the root folder. However, my application crashes when I try to reassign the parent ID for the file. Any ideas on how to successfully move files/folders? Any help is much appreciated! Thanks in advance!
Okay. I suppose there wasn't a way to do fix this in-house with the SDK. So, I had to send out an external PUT request. I used the following code to handle moving files.
- (void)moveItem:(BoxObject *)object toParentFolderWithID:(BoxID *)parentID
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.box.com/2.0/files/%#", object.boxID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"PUT"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *auth = [NSString stringWithFormat:#"BoxAuth api_key=%#&auth_token=%#",[Box boxAPIKey],[defaults objectForKey:#"box-api-auth-token"]];
NSString *payload = [NSString stringWithFormat:#"{\"parent\": {\"id\": %#}}", parentID];
[request setHTTPBody:[NSMutableData dataWithData:[payload dataUsingEncoding:NSUTF8StringEncoding]]];
[request setValue:auth forHTTPHeaderField:#"Authorization"];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
}
Just as a reminder if you are new to the Box SDK, you will most likely need to update/refresh the data after moving the files. If not handled, your application could crash if the file doesn't exist. Hope this helps to anyone was not sure about this.