anthonymdev / amazons3requestmanager Goto Github PK
View Code? Open in Web Editor NEWA request manager that uses Alamofire to serialize requests to the AWS S3 (Amazon Simple Storage Solution). Based on AFAmazonS3Manager
License: MIT License
A request manager that uses Alamofire to serialize requests to the AWS S3 (Amazon Simple Storage Solution). Based on AFAmazonS3Manager
License: MIT License
We should have parameters to set all of the parameters from the REST API for the listBucketObjects()
request method.
listBucketObjects()' to
README`For parameters see: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html
There should be a method to get an object and just return it in the response's responseObject
parameter.
This will likely not use the download
request, and instead be a normal GET
request. This means it won't allow use of progress blocks.
It possibly could still use progress blocks if I manually delete the temporary file and set the responseObject
. I'm not sure if this is possible yet.
Anthony, First of all, thanks for the very useful code you've submitted. I've written a small app (iOS 9.1, Xcode 7.1.1) to test upload/download/delete functionality. Uploading files to an S3 bucket and deleting them from the S3 bucket works fine.
However, I get an error "NoSuchKey" every time I try to download a file using ".downloadObject". The credentials are fine, because I can upload and delete with no problem. I verified that I successfully uploaded "anothertest.txt" to my bucket. The file contents are "This is a test". Here's a code snippet:
// This works fine
func UploadToCloud(theFileName: String, theContents: NSString) {
let theData: NSData = theContents.dataUsingEncoding(NSUTF8StringEncoding)!
amazonS3Manager.putObject(theData, destinationPath: theFileName)
}
// This fails every time with the same error
func DownloadToFile(theFileName: String) {
let destination: NSURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0].URLByAppendingPathComponent(theFileName)
print(destination.path!)
amazonS3Manager.downloadObject(theFileName, saveToURL: destination)
// quick hack to wait for completion
sleep(3)
// now read contents of file and print it
print(ReadTextFile(destination.path!))
}
-----------------------------------------------------------------------------------------------
The debug print statements produce the following:
/var/mobile/Containers/Data/Application/4FF3BA62-A446-4BD9-B260-7707A67ED74E/Documents/another.txt
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>anothertest.txt</Key><RequestId>118C265C26691052</RequestId><HostId>m2hed5lY29uSZccvG8O+rtHDln24PTpmbhNEaRvI3fS3V6rGZw2zdAevUjvEl7W+/rTu9mjj1mM=</HostId></Error>
Any idea what's wrong? Is this an Amazon S3 issue? Any help would be appreciated. Thanks!
Jon
@AnthonyMDev Hi anthony
Amazons3request manager hanlde chunk upload/download?
And yes then how to handle ? Its automatically request to server for check for resume?
Please provide some info how to handle chunk upload/download
Thank you
When uploading a file to a target path that contains spaces, I receive the following error:
Domain=com.AmazonS3RequestManager.error Code=-9999 "The request's signature doesn't match what we calculated. Please check that your S3 secret key matches your SX key, your S3 access key matches your SX username, and that the S3 base hostname is set to sx3.iml.unibe.ch." UserInfo={NSLocalizedFailureReason=The request's signature doesn't match what we calculated. Please check that your S3 secret key matches your SX key, your S3 access key matches your SX username, and that the S3 base hostname is set to sx3.iml.unibe.ch.}
Example file name: workingcopies/Rotation 2.Stomach.Peter Latch.crumble
According to http://stackoverflow.com/questions/7116450/what-are-valid-s3-key-names-that-can-be-accessed-via-the-s3-rest-api this kind of file names need some special treatment.
I tried to upload to my LibreS3 installation. I'm not sure if the same problem occurs when uploading to a official amazon bucket.
When trying to list a bucket using manager.amazonURLRequest(.GET, path : "")
the request fails because the S3 REST API doesn't accept a leading slash.
I've noticed that uploading files containing spaces or other special characters (ie. foreign language characters) in the name always fails with 403. Anybody else facing the same issue?
URLByAppendingPathComponent
in amazonURLRequest
method returns percent-encoded url so what could be the problem then?
The primary issue with adding linux is the reliance on CommonCrypto
, which requires the use of an Objective-C
class with a bridging header.
Possible alternatives to CommonCrypto
are Cipher
and Hash
(possibly the two combined).
The AmazonS3RequestSerializer
does not depend on Alamofire
and is able to be used with other networking libraries or a vanilla NSURLSession
.
This class and its dependencies should be refactored into another CocoaPod and this pod should depend on that one.
S3BucketObjectList
Currently uses this method to parse the files:
parseContents(xml["ListBucketResult"]["Contents"])
However, if you use a delimiter your results are here:
xml["ListBucketResult"]["CommonPrefixes"]
Therefore, if i've understood it correctly, using a delimiter with the current library doesn't return any results.
How would I go about setting the uploaded file's ACL to Public ?
Thanks.
I am getting error "Use of undeclared type Response" when trying to access bucket files. Is it compatible with Alamofire 4.0.1?
Great work btw.
S3 allows files to be copied from one location to another. AmazonS3RequestManager currently doesn't support that.
See: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html
When fetching meta data for an S3 object the S3ObjectMetaData
initializer crashes with a bad access exception. This is most likely due to the representation
parameter that is of typ Any
. This apparently leads to a memory problem because the representation object won't be retained until the end of the initializer.
I'm getting this build error:
AmazonS3RequestManager/AmazonS3RequestManager.h:29:9: Include of non-modular header inside framework module 'AmazonS3RequestManager.AmazonS3RequestManager'
when compiling the latest version installed using Cocoapods. This is using Xcode 7.1 beta 3 targeting iOS 9.1, in case it's an Xcode change.
It seems to not like the
line in the umbrella header file. Perhaps the Obj-C files aren't being added to the module map or something?
May be a bit annoying, but converting this file to Swift might be a solution.
Hello,
I'm having trouble to build a new project, that contains this pod file content:
`source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'AmazonS3RequestManager', '~> 0.10'`
When I try to insert your piece of code:
func initAWSManager() { let amazonS3Manager = AmazonS3RequestManager(bucket: myAmazonS3Bucket, region: .USStandard, accessKey: myAmazonS3AccessKey, secret: myAmazonS3Secret) }
a compiler error tells me that AmazonS3RequestManager is unresolved.
Am I missing something?
Thanks a lot
A Swift 2.3 release would be very much appreciated, since currently the absence of it breaks my whole build chain. My custom pod has a dependency on AmazonS3RequestManager and other frameworks but I cannot use Swift 3 yet because not all of the other frameworks support that yet.
Showing All Errors Only
/Users/romk1n/devel/myapp/Pods/AmazonS3RequestManager/Source/AmazonS3RequestSerializer.swift:130:23: Value of optional type 'NSURL?' not unwrapped; did you mean to use '!' or '?'?
/Users/romk1n/devel/myapp/Pods/AmazonS3RequestManager/Source/AmazonS3RequestSerializer.swift:246:34: Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
/Users/romk1n/devel/myapp/Pods/AmazonS3RequestManager/Source/AmazonS3RequestSerializer.swift:261:34: Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
/Users/romk1n/devel/myapp/Pods/AmazonS3RequestManager/Source/AmazonS3RequestSerializer.swift:261:21: Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
/Users/romk1n/devel/myapp/Pods/AmazonS3RequestManager/Source/AmazonS3RequestSerializer.swift:263:30: Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
I have been trying it, but it does not even show any messages about the wrong credentials etc. Returning an empty result.
Hey Anthony. Thanks for the great library.
Is it possible to use AmazonS3RequestManager to get a list of the contents of an S3 bucket or directory?
S3 allows custom meta data to be assigned to files. AmazonS3RequestManager currently doesn't allow to set or read this meta data.
See: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
we still need to support ios 8 devices, there shouldn't be anything which prevents this running on ios 8 right ?
The core of this library should not have a dependency on Alamofire
. Without Alamofire
you should still be able to serialize a URLRequest
for Amazon S3.
The Alamofire
manager should be an optional subspec.
This library should include support for generating Pre-Signed URLs
The Readme provides the following example for saving objects to file:
let destination: NSURL = FileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
amazonS3Manager.download(at: "myFolder/fileName.jpg", to: destination)
This code doesn't compile in Swift 3. The file manager API is outdated, and it seems that the download
method does not accept an NSURL as its to:
parameter. Please update with a working example.
Been using this library for a while and really like it. Migrating to Swift 3 is just a PITA in general. Cheers!
After cursory review, it seems like it wouldn't take much to make this OSX compatible, like AlamoFire is already. Is this a possibility?
Is there any reason the Swift 2 version is targeting Alamofire 1.3 instead of 2.0 ?
I'm not sure if this needs to be, or should be, a subclass of 'Alamofire.Manager'.
There are a few other options here.
Create a separate serializer for S3 requests with no dependency on 'Alamofire' and just allow that to be used.
Have a 'requestManager' property on the instance that is used to make all requests. If it is not set, the default manager is used.
I think there may be better options. I'm going to continue considering this.
I use a self hosted LibreS3 installation which provides S3 API REST compatibility. However the library currently doesn't allow for custom endpoints since the region parameter is an immutable enum.
I suggest that we either change the region to be a plain string and use something like .USStandard.rawValue
when calling the initialiser or we introduce a host
property that has priority over the region
property. Other ideas?
We should implement response handling to parse the Amazon S3 response.
An extension on Alamofire.Request
that adds a responseAmazonS3()
function seems like a good way of doing this.
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:61:39: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:90:35: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:120:35: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:152:35: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:158:35: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:61:31: warning: 'errorWithCode(_:failureReason:)' is deprecated
- WARN | xcodebuild: AmazonS3RequestManager/Source/AmazonS3ResponseSerialization.swift:117:27: warning: 'errorWithCode(_:failureReason:)' is deprecated
Amazon S3 only support upload objects up to 5 GB with a single PUT operation.
http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html
When app try to upload a object which is more than 5 GB size, this library returns 'success' without actual uploading.
If AmazonS3RequestManager supports multipart upload, it will be fixed. : )!
I have my bucket in Frankfurt (EUCentral1) and I receive this error:
FAILURE: Error Domain=com.AmazonS3RequestManager.error Code=-9999 "The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256." UserInfo={NSLocalizedFailureReason=The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.}
Is there anything I can do to fix this? Moving the bucket is not an option.
Thanks!
I tried to upload using amazonS3Manager.upload() like above code.
amazonS3Manager.upload(from: fileUrl, to: "sample+0.mp4")
But uploaded file name in s3 was "sample 0.mp4".
Can you fix this issue or give me some advise for me?
SWXMLHash needs to be updated to v4.1.0 to support swift 4
Removed Sequence from XMLIndexer to avoid a conflict with the element property coming in Swift 4
The official SDK provides an operation to find out in which region a bucket resides. This comes in handy because this information is sometimes not available.
AmazonS3RequestSerializer.swift:127:23: error: value of optional type 'NSURL?' not unwrapped; did you mean to use '!' or '?'?
url = url.URLByAppendingPathComponent(path)
^
!
AmazonS3RequestSerializer.swift:224:34: error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
let URLString = self.absoluteString.stringByAppendingString("?\(subresource)")
^
!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.