iosobjective-cnsxmlparsernsxmlparserdelegate

How to reload or update a viewController's view once a file is saved


Is it possible to reload/update a viewController's view once a file gets saved in the documents folder? If yes, kindly suggest how to accomplish this.

I'm trying to save a file in AppDelegate, but as it involves XML parsing, it is saved only when a view gets loaded. This is the view that is supposed to show the contents of the file. But as it gets loaded before the file is saved, the view doesn't display anything.

This query is related to my question at this link

Shall I share the code here again?


Solution

  • I can guide you through the process. What you need to implement is:

    1. When your file gets written to the storage, you can post a Notification through NotificationCenter. (Additionally you can check for the existence of the file immediately before posting the Notification).
    2. Add an observer for listening to that Notification through NotificationCenter in your ViewController (maybe inside viewDidLoad()).
    3. When you add the observer you need to specify a selector(method) which will be called when the notification occurs. So add a method and provide it as the selector for addObserver.
    4. Do your required operations in that method and at the last of the method mark your view dirty. It is usually done with self.view.setNeedsDisplay(). This will do the reloading/updating part.

    EDIT: added some code example

    Here I'm posting relevant code. Focus on the comments inside the code.

    AppDelegate.swift

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        postNotificationAfterFileSave()
        return true
    }
    
    func postNotificationAfterFileSave() {
        // do your job with your custom class's method for saving
        // you should get a filepath back
        CustomXMLParser().parseAndSave { (filePath) in
            if FileManager.default.fileExists(atPath: filePath) {
                // if the file exists, post Notification
                NotificationCenter.default.post(name: Notification.Name("FileWrittenCompletion"), object: nil)
            }
        }
    }
    

    ViewController.swift

    @IBOutlet weak var myLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // add an observer for your Notification and specify a selector that will be called when Notification is got
        NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: Notification.Name("FileWrittenCompletion"), object: nil)
        myLabel.text = "File is being saved"
    }
    
    @objc func updateUI() {
        // this method will be called when Notification happens
        // change your UI objects according to your needs
        myLabel.textColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
        myLabel.text = "File is saved successfully"
        // Finally mark your view `dirty` that will do the reloading task of the UI
        self.view.setNeedsDisplay()
    }
    

    CustomXMLParser.swift

    func parseAndSave(completion: @escaping (String)-> Void ) {
        let when = DispatchTime.now() + 10
        DispatchQueue.global().asyncAfter(deadline: when) {
            let string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
            // get the document directory
            let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("myFile").appendingPathExtension("txt")
    
            do {
                // write to filepath
                try string.write(to: fileURL!, atomically: true, encoding: .utf8)
    
                DispatchQueue.main.async {
                    // return the filePath through completion block
                    completion((fileURL?.path)!)
                }
    
            } catch {
                print("\(error.localizedDescription)")
            }
    
        }
    }