0

I am inserting images into a TextKit textView using an NSMutableAttributed string and NSAttachment with the following Swift imagePickerController code:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
            picker.dismiss(animated: true, completion: nil)
            if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            
                let alert = UIAlertController(title: "Insert Image", message: "Do you wish to insert the selected image?", preferredStyle: UIAlertController.Style.alert)
               
                let defaultAction = UIAlertAction(title: "Insert Image", style: UIAlertAction.Style.default, handler: { [self]
                    (action:UIAlertAction!) -> Void in
                let attachment = NSTextAttachment()
                attachment.image = pickedImage
                    
                    //save to app directory using this function below
                       saveImageToDocumentDirectory(image: pickedImage )
                    
                    //save to UserDefaults directory using this call below as alternate
                       let imageData:NSData = pickedImage.pngData()! as NSData
                     
                       UserDefaults.standard.set(imageData, forKey: "keyp2Image")
                  
                    let imageattributedText = NSMutableAttributedString(attachment: attachment)
                    if let selectedRange = textView.selectedTextRange {
                        let cursorPosition = textView.offset(from: textView.beginningOfDocument, to: selectedRange.start)
                        
                        textView.textStorage.insert(imageattributedText, at:cursorPosition)
                        attrString.append(imageattributedText)
                        self.textView.font = UIFont.systemFont(ofSize: 17)
                     
                            
                    }
                   
                   
        })
                let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: {
                    (action:UIAlertAction!) -> Void in
                    print("Cancel")
                })
             
               
                alert.addAction(cancelAction)
                alert.addAction(defaultAction)
               
                present(alert, animated: true, completion: nil)
                
            }

    }

The above code saves images to either NSUserDefaults or to the application directory, however, my problem is I cannot get the saved images to reload using the following ViewDidLoad code snippet below:

 let defaults = UserDefaults.standard
    
    if let savednotes = defaults.object(forKey: "newnotes") as? Data {
        let jsonDecoder = JSONDecoder()

        do {
            notes = try jsonDecoder.decode([Note].self, from: savednotes)
        } catch {
            print("Failed to load notes")
        }
    }
  }

Question: What would the optimum method to reload both images and text simultaneously (text is reloading fine) using the above json decoder code. I have been banging on this for a while with not much success. Any suggestions appreciated.

user46938
  • 59
  • 4
  • 2
    Why are you storing stuff like this into user defaults? You can simple convert that attributed string to an rtf file, and save it as a file instead. Loading the file would also become very simple. There's no need to save the image separately. – Sweeper Jul 19 '21 at 10:48

1 Answers1

0

NSAttributedString has methods that converts it to Data if you specify a format, and initialisers that take Data as parameters. You can then write that Data to a path you like. Your Note objects can then store URLs that point to the files. There are many formats you can choose from. Choose one that supports attachments.

Here's how you would save and load NSAttributedStrings to files:

// saving
let data = try attributedString.data(from: NSRange(location: 0, length: attributedString.length),
                                     documentAttributes: [.documentType:
                                                            NSAttributedString.DocumentType.rtfd])
try data.write(to: URL(fileURLWithPath: "some path"))

// loading
let dataRead = try Data(contentsOf: URL(fileURLWithPath: "some path"))
let loadedAttributedString = try NSAttributedString(data: dataRead,
                                                options: [.documentType:
                                                            NSAttributedString.DocumentType.rtfd],
                                                documentAttributes: nil)
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • This question was about saving and loading `NSAttributedString`s. Those seem to be separate problems. You should produce a [mcve] (not a download link) and post a new question. @user46938 – Sweeper Aug 25 '21 at 08:41
  • Will repost an additional question with sample code! – user46938 Aug 25 '21 at 08:47