Not able to upload more then 5GB video file into AWS S3 bucket - ios

I’m using AWS to upload videos from my App.
I can able to upload up to 5 GB single video without any problem with AWSS3TransferUtilityTask.
My requirement is I want to upload more than 5 gb video file.(e.g 7GB, 10GB , 13GB)
I’ve tried with AWSS3TransferUtilityMultiPartUploadTask to upload more then 5 gb files. After completing more then 60% of upload I'm getting an error (NSURLErrorDomain error -1001).
// Completion Handler
let completionHandler : AWSS3TransferUtilityMultiPartUploadCompletionHandlerBlock? =
{ (task, error) -> Void in
if ((error) != nil)
{
print("------------------>",error?.localizedDescription ?? "")
}
else
{
print("File uploaded successfully")
}
}
//Expression
let expression = AWSS3TransferUtilityMultiPartUploadExpression()
expression.progressBlock = progress
//Content Type
let contentType = "video/mp4"
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadUsingMultiPart(fileURL: uploadingFileURL, bucket: bucket, key: path + filename, contentType: contentType, expression: expression, completionHandler: completionHandler)
}
else {
print(" session out----->",jsonData)
}
Thanks in advance.

Related

AWSS3TransferUtilityErrorDomain Code=2 on iOS Swift While trying to upload Image/pdf

I am trying to upload pdf file or image file to AWSS3 bucket but I am getting AWSS3TransferUtilityErrorDomain Code=2 error. Please note I already have checked region and it is correct. Also I have verified that I am using correct accessKey and secretKey I also have visited below mentioned links with no luck:
(https://github.com/aws-amplify/aws-sdk-ios/issues/2553.)
(https://github.com/aws-amplify/aws-sdk-ios/issues/604)
(https://github.com/aws-amplify/aws-sdk-ios/issues/420)
(https://github.com/aws-amplify/aws-sdk-ios/issues/103)
(Upload image to S3 with Amazon Educate Starter Account)
(About permission in S3 file transfer)
(Swift iOS: Unable to Upload Image to AWS S3)
(AWSS3TransferUtilityErrorDomain Code=2 on ios)
My code to upload file is below:
let credentials = AWSStaticCredentialsProvider(accessKey: “accessKey” , secretKey: “secretKey”)
let configuration = AWSServiceConfiguration(region: AWSRegionType.APSouth1 , credentialsProvider: credentials)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = { (task, progress) in
DispatchQueue.main.async(execute: {
// Update a progress bar
print("Task: \(task)")
print("Progress: \(progress)")
})
}
var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if let error = error {
CommonLoader.hide()
SCLAlertView().showError("Error", subTitle: error.localizedDescription)
return
}
// Do stuff after success
})
}
let transferUtility = AWSS3TransferUtility.default()
// contentType —-> “image/jpeg” for images && “application/pdf” for pdf files
transferUtility.uploadData(data, bucket: s3BucketName, key: remoteName, contentType: contentType, expression: expression, completionHandler: completionHandler).continueWith { (task) -> Any? in
if let error = task.error {
// error case
}
else {
if !task.isFaulted && task.result != nil {
// success case
}
}
return nil
}
After a lot of search and reading documentation I am able to solve this issue.
In my case there were two strange things, one with same credentials and bucket on Android it was working.
But on iOS exactly same code was working in Dubai but not in Pakistan.
I solved the issue by just adding the region to project info.plist file as mentioned below:
Please note in my case region was ap-south-1 but you need to put it here yours, you can check region from Amazon S3 Endpoints and then find corresponding region value to use in your info.plist. Hope this will help someone and save time. Happy coding. cheers!
<key>S3TransferUtility</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>"ap-south-1"</string>
</dict>
</dict>

Error 13010 "Object does not exist" while downloading jpeg image from Firebase storage using getData()

Language : Swift 5
iOS: 13.2
macOS: Catalina 10.15.4
Firebase Storage Rules:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth!=null;
}
}
}
The code to upload image and save download URL: (Which works fine, because I can see images uploaded to storage and their respective download URLs stored to real-time database.)
let storageRef = Storage.storage().reference()
//Let's upload all workout pictures
let uploadPicsRef =
storageRef.child("WORKOUTDATA/USERS/"+self.UID!).child("WHITEBOARDWORKOUTS")
let uploadNumberRef = uploadPicsRef.child("\(String(describing: workoutNum))")
let workoutPicturesRef = uploadNumberRef.child("WORKOUTPICTURES")
let workoutPicURLRef = workoutRef.child("WORKOUTPICTURESURL")
var count = 0
var picNumber = 0
//workoutPictures list/array contains images selected from iPhone Gallery, using
//UIImagePickerController
for workoutPic in self.workoutPictures
{
let workoutPicData = workoutPic.jpegData(compressionQuality: 1.0)!
count = count + 1
let pictureName = "Picture\(count).jpg"
// Upload the file to the path in pictureRef
let pictureRef = workoutPicturesRef.child("\(pictureName)")
let metaData = StorageMetadata()
metaData.contentType = "image/jpg"
pictureRef.putData(workoutPicData, metadata: metaData) { (metadata, error) in
if error != nil {
print("Error while uploading image")
}
else
{
pictureRef.downloadURL { (url, err) in
picNumber = picNumber + 1
workoutPicURLRef.child("Picture\(picNumber)").setValue(url?.absoluteString)
}
}
}
}
The code to download image:
let myGroup = DispatchGroup()
let workoutPicUrls = snapshot.childSnapshot(forPath: "WORKOUTPICTURESURL")
for url in workoutPicUrls.children
{
myGroup.enter()
let snap = url as! DataSnapshot
let link = snap.value as? String
let storageRef = Storage.storage().reference()
let pictureRef = storageRef.root().child(link!)
DispatchQueue.main.async {
pictureRef.getData(maxSize: 1*2000000*2000000) { (data, err) in
if (err != nil) {
print(err!)
print(err!.localizedDescription)
} else {
let pic = UIImage(data: data!)
workoutPicsArray.append(pic!)
myGroup.leave()
}
}
}
}
Error:
Error Domain=FIRStorageErrorDomain Code=-13010 "Object https:/firebasestorage.googleapis.com/v0/b/trainer-8cb52.appspot.com/o/WORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547 does not exist." UserInfo={object=https:/firebasestorage.googleapis.com/v0/b/trainer-8cb52.appspot.com/o/WORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547, ResponseBody={
"error": {
"code": 404,
"message": "Not Found. Could not get object",
"status": "GET_OBJECT"
}
}, bucket=trainer-8cb52.appspot.com, data={length = 115, bytes = 0x7b0a2020 22657272 6f72223a 207b0a20 ... 54220a20 207d0a7d }, data_content_type=application/json; charset=UTF-8, NSLocalizedDescription=Object https:/firebasestorage.googleapis.com/v0/b/trainer-8cb52.appspot.com/o/WORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547 does not exist., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=404}
What I have tried so far:
Checked firebase storage rules.
When I paste the path https:/firebasestorage.googleapis.com/v0/b/trainer8cb52.appspot.com/o/WORKOUTDATA%2FUSERS%2F1K7WV1alYIeWPAsFC6YMoJKPFSj1%2FWHITEBOARDWORKOUTS%2F5%2FWORKOUTPICTURES%2FPicture1.jpg?alt=media&token=785ab8c7-1e08-4ad3-a542-c9e6313eb547 in chrome browser window, the expected image opens.
Set the maxSize to a ridiculously high number 1*2000000*2000000.
Thank you!
Is it possible that you are storing the full https URL in the database and are trying to create a reference by adding the full https url as a child to the storage reference?
I think you should try to either store just the path and name in your database or you change your download code to use the https URL.
// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
let httpsReference = storage.reference(forURL: "https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg")
httpsReference.getData(maxSize: ...
Also you're running your getData method inside DispatchQueue.main.async. getData has itself a completion handler and might take some time, when you run that inside of DispatchQueue.main.async it will block your code until the download is done. Only put code that update the UI inside DispatchQueue.main.async. In your case as soon as you do something with your workoutPicsArray or the UIImage to update your view.
Have a look here to see if you can figure out how you are actually trying to get the data. It might be helpful to put a print() after each line to see what you are creating and using at what point.
Download Files on iOS

How to upload a video from iOS photo album to Azure Blob Storage

I am struggling with uploading videos from iOS photo album to Azure blob storage. I am using AZSClient.
uploading images is straight forward, ie. I get the image 'Data' from PHAsset and then upload it to azure storage using AZSCloudBlockBlob.uploadFromData method
Can anyone guide me on how to upload a video to azure blob preferably in swift
There was a similar thread for this they used the bellow code, and they used the IOS library found here:
//Upload to Azure Blob Storage with help of SAS
func uploadBlobSAS(container: String, sas: String, blockname: String, fromfile: String ){
// If using a SAS token, fill it in here. If using Shared Key access, comment out the following line.
var containerURL = "https://yourblobstorage.blob.core.windows.net/\(container)\(sas)" //here we have to append sas string: + sas
print("containerURL with SAS: \(containerURL) ")
var container : AZSCloudBlobContainer
var error: NSError?
container = AZSCloudBlobContainer(url: NSURL(string: containerURL)! as URL, error: &error)
if ((error) != nil) {
print("Error in creating blob container object. Error code = %ld, error domain = %#, error userinfo = %#", error!.code, error!.domain, error!.userInfo);
}
else {
let blob = container.blockBlobReference(fromName: blockname)
blob.uploadFromFile(withPath: fromfile, completionHandler: {(NSError) -> Void in
NSLog("Ok, uploaded !")
})
}
}
I found the answer in this thread
let manager = PHImageManager.default()
manager.requestAVAsset(forVideo: asset, options: nil, resultHandler: { (avasset, audio, info) in
if let avassetURL = avasset as? AVURLAsset {
guard let video = try? Data(contentsOf: avassetURL.url) else {
return
}
videoData = video
}
})
once you get the Data object then you can use AZSCloudBlockBlob.uploadFromData to upload it to azure storage

How to edit the file in swiftyDropbox?

In my project, I uploaded all my text files to the Dropbox. Here, I need to directly edit the uploaded file in Dropbox using swift. Is it possible to edit files in Dropbox?
(OR) Is it possible to overwrite the same fileName in Dropbox?
Solution moved from #SathishKumarGurunathan's question post.
I found the answer and I will share here.
_ = client?.files.upload(path: path, mode: .overwrite, autorename: false, clientModified: nil, mute: false, input: Description).response { response, error in
if let response = response {
print("The upload response is \(response)")
} else if let error = error {
print("The upload error is \(error)")
}
}
.progress { progressData in
print("The progress Data is \(progressData)")
}

Unable save large file to S3 using Parse server

I tried to save to S3 bucket using Parse Server, and it can be saved correctly when the file is small, such as 864.2KB. However, when the file is large, say 5MB, it complaints with a message saying: "The data couldn’t be read because it isn’t in the correct format"
I'm using the following code to save the the video file to the S3
func saveVideo(withVideoURL url: URL){
let post = PFObject(className: "Post")
post["caption"] = "Out of the game for 6 months, but back with vengeance. Meet your 2017 AO Men's champion"
do{
let data = try Data(contentsOf: url)
print(data)
post["media"] = PFFile(data: data)
post.saveInBackground { (success, error) in
if success{
print("video saved")
}else{
print("failed")
if error != nil{
print(error!.localizedDescription)
}else{
print("erorr is nil")
}
}
}
}catch let error as NSError{
print("can't read")
print(error.localizedDescription)
}
}
Besides, even when the small video file is indeed being saved to the S3, it contains an extension .bin instead of, for example .mp4. I wonder what's happening here
The url end up looking something like this
https://s3-us-west-1.amazonaws.com/sampleApp/19d5bce20f8b55te1b1b8f370212533e5_file.bin
You need to stipulate the content type. You can do so like this:
post["media"] = PFFile(data: data, contentType: "video/mp4")
The below settings in your parse-server index file will help you:
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '20mb'}));
app.use(bodyParser.urlencoded({limit: '20mb', extended: true}));
If you are using elastic beanstalk, you have to have a file named files.config inside the folder .ebextensions, with the below content.
files:
/etc/nginx/conf.d/proxy.conf:
content: |
client_max_body_size 20M;
This fixed the issue for me.

Resources