How do you persist a custom Swift struct to JSON in Documents?

Tests fluency with Codable and FileManager sandbox APIs. Good answer: conform to Codable, encode with JSONEncoder, resolve Documents directory via FileManager URLs, write Data atomically, and reverse with JSONDecoder.
What's really being asked
This question probes whether you know the platform-idiomatic way to serialize custom types in Swift. The interviewer wants to hear Codable as the default contract between your model and JSON, paired with FileManager for sandbox-aware file URLs. For a senior candidate, it is also a check against unnecessary complexity like third-party serialization libraries or manual Dictionary mapping when the standard library already solves the problem.
The full answer
First, declare that the struct conforms to Codable, which gives you automatic synthesized encoding and decoding as long as every stored property is also Codable. Second, describe the write path: instantiate JSONEncoder, call encode on your struct to produce Data, then locate the Documents directory by calling FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) and appending your filename. Third, write that Data to disk using write(to:options:), mentioning that you can pass .atomic for safe writes. Fourth, describe the read path: initialize Data with contentsOf the file URL, then use JSONDecoder to decode back into your struct type. Fifth, mention error handling with do-catch or Result, because any of these steps can throw.
The mistakes people make
Using NSSearchPathForDirectoriesInDomains instead of the URL-based FileManager API is an older pattern that signals stale knowledge. Building JSON by hand with string interpolation or Dictionary serialization is a red flag for ignoring Codable. Force-trying every step with try! or silently discarding errors with try? without discussion shows a lack of production awareness. Attempting to write into the main bundle instead of Documents or Library indicates misunderstanding of the iOS sandbox. Finally, forgetting that Codable synthesis requires all nested types to also conform to Codable will cause a compile-time failure that a candidate should be able to explain.
What usually comes next
The interviewer may ask how you would handle schema changes or versioning if you add a new property to the struct later. They might also ask about custom encoding keys if the JSON keys should differ from the property names. Another angle is performance: how large can this file get before you should switch to Core Data or SQLite? They could also ask about concurrency, such as whether you perform these operations on a background queue to avoid blocking the main thread.
A concrete example
Imagine a struct named UserSettings with two properties, var theme: String and var notificationsEnabled: Bool. To persist it, you create let encoder = JSONEncoder(), then let data = try encoder.encode(userSettings). You resolve the file URL with let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!, then let fileURL = documentsDirectory.appendingPathComponent("settings.json"). Finally, you call try data.write(to: fileURL, options: .atomic). To read it back, you use let data = try Data(contentsOf: fileURL) and let decoded = try JSONDecoder().decode(UserSettings.self, from: data).
Interview question
Which approach correctly persists a custom Swift struct to a JSON file in the Documents directory?
- a.Conform the struct to Codable, encode with JSONEncoder, resolve the Documents directory via FileManager.default.urls(for:in:), and write the resulting Data with the atomic option.Correct
- b.Use NSSearchPathForDirectoriesInDomains to get a path string, manually build a JSON string from the struct's properties, and write to that path.
- c.Manually convert the struct to a Dictionary, use JSONSerialization to produce Data, and write to the Documents directory via FileManager.default.urls(for:in:).
- d.Encode the struct with JSONEncoder using try!, then write the resulting Data to a file URL located in the app's main bundle.
Why? this is the answer
Option A is correct because Codable provides automatic synthesized JSON encoding, and the URL-based FileManager API with atomic writes is the modern, sandbox-safe way to persist data in Documents. Option B is a tempting distractor because it uses FileManager, but it relies on the legacy NSSearchPathForDirectoriesInDomains string API and manual JSON construction instead of Codable.
Just read this? Test yourself on what you have been reading.
Read the original → developer.apple.com
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on ios — each one lists the topics its interview covers.
See open roles