Question

How can a Swift app save window size and location for restart?

Answer and Explanation

To save a Swift app's window size and location for restart, you can utilize the UserDefaults class. Here's a detailed guide on how to achieve this:

1. Access the Window’s Frame:

- In your NSWindowController or the class handling your window, retrieve the window's frame using window?.frame. This gives you a CGRect representing the window's size and position.

2. Convert CGRect to Data for Saving:

- Since UserDefaults can’t directly store CGRect, convert it into Data using NSKeyedArchiver. This will allow you to easily save and retrieve complex data.

3. Save the Window Frame in UserDefaults:

- Use UserDefaults.standard.set(_:forKey:) to save the Data object under a specific key like "windowFrame".

4. Retrieve the Saved Window Frame:

- When your app restarts or when the window is loaded, retrieve the saved data from UserDefaults.standard.data(forKey:) using the same key. Then unarchive it back into a CGRect.

5. Set the Window’s Frame:

- Set the retrieved CGRect as the window's frame with window?.setFrame(_:display:)

6. Example Swift Code for Saving:

func saveWindowFrame() {
  if let frame = window?.frame {
    if let data = try? NSKeyedArchiver.archivedData(withRootObject: frame, requiringSecureCoding: true) {
      UserDefaults.standard.set(data, forKey: "windowFrame")
    }
  }
}

7. Example Swift Code for Loading:

func loadWindowFrame() {
  if let data = UserDefaults.standard.data(forKey: "windowFrame"),
     let frame = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSValue.self, from: data) as? CGRect {
    window?.setFrame(frame, display: true)
  }
}

8. When to Call These Functions:

- Call saveWindowFrame() before your window closes or in response to an event like windowWillClose notification.

- Call loadWindowFrame() when your window is created or restored, such as in windowDidLoad in your NSWindowController or during the application's startup process.

9. Ensuring Secure Coding:

- Using requiringSecureCoding: true when archiving is vital for security, especially when storing data in user defaults.

10. Handling First Launch:

- Check if there's any data in UserDefaults when the app launches; if no data is found, you can set a default window frame.

By following these steps, your Swift application will save and restore the window size and location effectively. This ensures a consistent user experience across multiple sessions.

More questions