1

I am attempting to upload an image file(.jpg) and a pdf file(.pdf) at the ssme time using Alamofire. I keep getting the following error which indicates that the files that I am trying to upload does not exist, which in fact they do.

 multipartEncodingFailed(Alamofire.AFError.MultipartEncodingFailureReason.bodyPartFileNotReachableWithError(atURL: file:///var/mobile/Containers/Data/Application/7FF74F06-CD6E-47D6-850E-45E768C00D97/Documents/tempImage_wb.jpg, error: Error Domain=NSCocoaErrorDomain Code=260 "The file “tempImage_wb.jpg” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/7FF74F06-CD6E-47D6-850E-45E768C00D97/Documents/tempImage_wb.jpg, NSFilePath=/var/mobile/Containers/Data/Application/7FF74F06-CD6E-47D6-850E-45E768C00D97/Documents/tempImage_wb.jpg, NSUnderlyingError=0x1c4841020 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}))

My code for uploading the files:

 // GET URL FOR IMAGE AND PDF FILES
    guard
        let imageURLString = UserDefaults.standard.string(forKey: "URL_IMAGE"),
        let pdfURLString = UserDefaults.standard.string(forKey: "URL_PDF") else{return}


    guard
        let imgURL = URL.init(string: imageURLString),
        let pdfURL = URL.init(string: pdfURLString) else{return}

    var arrayURLToUpload: [URL] = []
    arrayURLToUpload.append(imgURL)
    arrayURLToUpload.append(pdfURL)



 let sendParamters = ["user_id": "1", "hashTagArray": jsonArrayHashTags]
    Alamofire.upload(
        multipartFormData: { multipartFormData in
            for(key, value) in sendParamters{
                multipartFormData.append((value.data(using: .utf8)!), withName: key)
            }

            for fileURL in arrayURLToUpload{
                print("fileURL: \(fileURL)")
                multipartFormData.append(fileURL, withName: "file[]")
            }
    },
        to: UPLOAD_URL,
        encodingCompletion: { encodingResult in
            switch encodingResult {
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    debugPrint(response)
                }

                /**TRACK PROGRESS OF UPLOAD**/
                upload.uploadProgress { progress in
                    print(progress.fractionCompleted)


                }
                /***/


            case .failure(let encodingError):
                print(encodingError)
            }
        }
    )

console:

 fileURL: file:///var/mobile/Containers/Data/Application/7FF74F06-CD6E-47D6-850E-45E768C00D97/Documents/tempImage_wb.jpg
 fileURL: file:///var/mobile/Containers/Data/Application/7FF74F06-CD6E-47D6-850E-45E768C00D97/Documents/tempImagePDF.pdf

I know the files exist becuase when I retrieve one of the files (.pdf) and display it I am able to view the stored pdf file:

    guard let urlString = UserDefaults.standard.string(forKey: "URL_PDF") else{return}

    guard let pdfURL = URL.init(string: urlString) else{
        print("no pdf URL")
        return

    }
    print("pdfURL: \(pdfURL)")

    guard let pdf = PDFDocument.init(url: pdfURL) else{
        print("NO PDF DOCUMENT FOUND")
        return

    }

    pdfPreview.document = pdf // CAN VIEW PDF FILE!!!
    pdfPreview.autoScales = true

    print("pdf document displayed!")

console:

 pdfURL: file:///var/mobile/Containers/Data/Application/90ECD1AE-B9A5-46C9-AD30-C5D8D850A361/Documents/tempImagePDF.pdf

 pdf document displayed!

How I generate my URLs:

 // Create a URL to save PDF
func createPdfURL() -> URL {

    let fileName = "tempImagePDF.pdf"

    let documentsDirectories = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentDirectory = documentsDirectories.first!
    let pdfPageURL = documentDirectory.appendingPathComponent("\(fileName)")

    return pdfPageURL
}

Then I save the PDF document as follows:

 // SAVE PDF TO LOCAL FILE SYSTEM
func savePdfToLocaFile(pdf: PDFDocument) -> Void {

    // CREATE URL FOR PDF DOCUMENT
    let pdfURL = createPdfURL()
    print("PDF SAVED TO URL: \(pdfURL)")

    self.pdfDocumentURL = pdfURL

    pdf.write(to: pdfURL)


}

I have also tried the following to retrieve the files by reconstructing the URL from the file name before using it to upload the files:

 // CONSTRUCT URL FROM FILE NAME
    let imgFileName = "tempImage_wb.jpg"
    let pdfFileName = "tempImagePDF.pdf"

    var dir: URL!
    do {
        dir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    } catch{
        print("error re-creating url")
    }

    let imgURL = dir.appendingPathComponent(imgFileName)
    let pdfURL = dir.appendingPathComponent(pdfFileName)

new console reading after implementing @vadian's suggestion:

PDF SAVED TO URL: file:///var/mobile/Containers/Data/Application/35C9D3EE-2D0C-4028-BCF3-2FE4581A0686/Documents/tempImagePDF.pdf
fileURL: file:///var/mobile/Containers/Data/Application/35C9D3EE-2D0C-4028-BCF3-2FE4581A0686/Documents/tempImagePDF.pdf

1 Answer 1

3

Please note the different application container identifier 7FF74F06-CD6E-47D6-850E-45E768C00D97 and 90ECD1AE-B9A5-46C9-AD30-C5D8D850A36.

Container locations change periodically therefore never save full paths pointing to the application container to UserDefaults. Save only the file names and get the URL to the current document directory always with

let documentsFolderURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

Then append the file name with .appendingPathComponent

Note: The try! is safe because the document directory is always created by the framework.

Sign up to request clarification or add additional context in comments.

1 Comment

why does document url not change and photo url changes?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.