Mitchell
Mitchell

Reputation: 343

No such file location - Uploading image from Swift to S3

I am trying to upload an image to Amazon S3 but I am getting the following error:

Optional(Error Domain=NSCocoaErrorDomain Code=260 "The file “asset.JPG” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/asset.JPG, NSUnderlyingError=0x7fb0d8eb3b00 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}})

The below code is where I am getting the image or videos file path - it is stored in the variable 'fileLocation':

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    //let mediaType2 : UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    let mediaType : CFString = info[UIImagePickerControllerMediaType] as! CFString



    //if video - save it
    if mediaType == kUTTypeMovie {
        let path = (info[UIImagePickerControllerMediaURL] as! NSURL).path
        if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path!) && saveVideoVar == true{
            UISaveVideoAtPathToSavedPhotosAlbum(path!, self, "video:didFinishSavingWithError:contextInfo:", nil)
        }
    }
    else{
        let img : UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        let screenSize: CGRect = UIScreen.mainScreen().bounds

        var multiplyNum = screenSize.width / img.size.width
        //if image height is going to be more than 60% of the screen, resize width and height to ensure that it isn't greater than 60% while keeping the aspect ratio correct
        if ((img.size.height*multiplyNum) > (screenSize.height*0.6)){
            multiplyNum = screenSize.height*0.6 / img.size.height
            imageViewWidthConstraint.constant = (multiplyNum*img.size.width)
            imageViewHeightConstraint.constant = screenSize.height*0.6
        }
        else{
            imageViewWidthConstraint.constant = screenSize.width
            imageViewHeightConstraint.constant = (multiplyNum*img.size.height)
        }
        imageView.image = img

    }
    let fileLocation: NSURL = info["UIImagePickerControllerReferenceURL"] as! NSURL
    nwyt.uploadS3(fileLocation)

    self.dismissViewControllerAnimated(true, completion: {})

}

No matter which photo I chose, it always gives the same error that the file "asset.JPG" couldn't be opened..." even though when I print the fileLocation, the path is more complex than that, as an example: "assets-library://asset/asset.JPG?id=EC41AC54-CEBD-49AA-A1FA-864370D103C0&ext=JPG"

Implementation of nwyt.uploadS3() :

func uploadS3(fileBody : NSURL){
    let uploadRequest: AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest.bucket = "bx-video"
    uploadRequest.key = "testObject.jpg"
    uploadRequest.body = fileBody
    print(fileBody)

    let transferManager: AWSS3TransferManager = AWSS3TransferManager.defaultS3TransferManager()
    transferManager.upload(uploadRequest).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {(task: AWSTask) -> AnyObject! in
        if task.error != nil {
            print(task.error)
            NSLog("Error uploading : " + uploadRequest.key!)
        }
        else {
            NSLog("Upload completed : " + uploadRequest.key!)
        }
        return nil
    })
}

Upvotes: 3

Views: 3348

Answers (4)

sanjay kumar
sanjay kumar

Reputation: 1

I have received same error Code=260 while trying to upload photo from the shared extension. The solution for this kind of problem is don't try to upload the image from its path rather upload the Data with file name. This worked for me by using https://github.com/daltoniam/SwiftHTTP api.

Below function to upload: Upload(data: Data, fileName: String, mimeType: String)

Upvotes: 0

Vitalii
Vitalii

Reputation: 4437

"assets-library://..." is not directly accessible. But you can use PHImageManager (iOS8+) to find the file in the assets library and copy it in your app's sandbox, then use the URL to the newly created file to upload or do whenever you want. Example code can be found in this answer to question How to upload image that was taken from UIImagePickerController.

Note that solution by @Mitchell is much simpler but has one serious drawback - the image will be converted to PNG (or to JPEG if you use UIImageJPEGRepresentation instead). JPEG -> PNG conversion will give increase in size and PNG -> JPEG might loose quality. In any case this won't be that original image any more.

Upvotes: 0

Mitchell
Mitchell

Reputation: 343

Solution below:

if let img : UIImage = imageView.image! as UIImage{
                let path = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("image.png")
                let imageData: NSData = UIImagePNGRepresentation(img)!
                imageData.writeToFile(path as String, atomically: true)

                // once the image is saved we can use the path to create a local fileurl
                let url:NSURL = NSURL(fileURLWithPath: path as String)
                nwyt.uploadS3(url)

            }

Upvotes: 3

Yosuke
Yosuke

Reputation: 3759

AWSS3TransferManager does not support ALAssetsLibrary. You need to copy the file to your app disk space and pass the file NSURL. See this sample as an example.

Upvotes: 1

Related Questions