1

I am a little lost on my quest to -

  1. Download a CKAsset (PDF File)
  2. Assign a Temporary Filename
  3. Write the contents of the CKAsset to the filename

I have managed to download the CKAsset and display the contents in a UIWebView, however I am stumbling over steps 2 and 3, I have a filename from a String, and despite trying a variety of WriteToFile combinations I receive errors.

My code is thus :

let filename = record.object(forKey: "materialsFilename")

                        if  materialsType == "PDF" || materialsType == "pdf" {


                            if let asset1 = record.object(forKey: "materialsFile") as? CKAsset {
                                let doc1Data : NSData? = NSData(contentsOf:asset1.fileURL)

                                let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename as! String)


                                let contentsOfFile = doc1Data
                                var error: NSError?

                                // Write File
                                if contentsOfFile.writeToFile(path, atomically: true, encoding: String.Encoding.utf8, error: &error) == false {
                                    if let errorMessage = error {
                                        print("Failed to create file")
                                        print("\(errorMessage)")
                                    }
                                } else {
                                    print("File \(filename) created at tmp directory")
                                }

This version presents the error -

Cannot invoke 'writeToFile' with an argument list of type '(URL?, atomically: Bool, encoding: String.Encoding, error: inout NSError?)'

The temporary file once created will be passed to a UIActivityViewController, to print / email / airdrop the PDF, having only a CKAsset name, the the UIActivityViewController cannot associate the file type to any of the users installed apps, save for print.

Bowcaps
  • 127
  • 2
  • 11
  • Can you set a breakpoint before "contentsOfFile.writeToFile"? -> What value does "path" have. If its null, it will not work to write to the specific file. Maybe te filename is somehow wrong ? The other option: Set breakpoint at the end. What does "error" contain? – Lepidopteron Apr 05 '17 at 10:21
  • The path at that stage appears to be the CKAsset path - path=~/Library/Caches/CloudKit/48e71b0c5ca5e4eb9add0599a376bae1d958ed3e/Assets/40118308-8136-4A66-8321-66AD609798A6.01707e7ffadfd047f02bc4a1579e6bcd2dbadf2c0b, size=268270, UUID=40118308-8136-4A66-8321-66AD609798A6, signature=<01707e7f fadfd047 f02bc4a1 579e6bcd 2dbadf2c 0b – Bowcaps Apr 05 '17 at 11:01
  • Are you allowed to write to the Cloud / use the iCloud of the user? – Lepidopteron Apr 05 '17 at 16:39

3 Answers3

1

After a little head scratching and reviewing my choices following the pointers above, I changed tack and didn't really need to write to a file, just rename the CKAsset, which I achieved with the following script -

let materialsType = record.object(forKey: "materialsType") as! String

                        let filename = record.object(forKey: "materialsFilename") as! String

                        if  materialsType == "PDF" || materialsType == "pdf" {

                            if let asset1 = record.object(forKey: "materialsFile") as? CKAsset {

                                let doc1Data : Data? = Data(contentsOf:asset1.fileURL) as Data?
                                let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename)
                                self.materialsWebView.load(doc1Data! as Data, mimeType: "application/pdf", textEncodingName: "UTF-8", baseURL: NSURL() as URL)
                                self.filenameURL = [(fileURL)]
                            }

The key seemed to hinge on two lines -

let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename)

and

self.filenameURL = [(fileURL)]

Which generates the filename for the UIActivityViewController and thus opens up the access to a number of additional Apps.

Bowcaps
  • 127
  • 2
  • 11
0

Are you sure you're using the correct writeToFile method? The NSData reference doesn't show a method with the same signature you're using. Try using one of the ones listed in the reference.

Matthew Hallatt
  • 1,310
  • 12
  • 24
0

I only find the following function in Data class.

func write(to: URL, options: Data.WritingOptions)

Try this.

Lumialxk
  • 6,239
  • 6
  • 24
  • 47