如何利用Core Data在离线状态下展示JSON数据
Solution for Offline Core Data Loading in TableView
Hey there! Let's get your offline data display working properly. The main gaps in your current code are that you only populate your iteamsArray during online downloads, and you don't prioritize local Core Data data when offline. Here's the revised code with clear explanations:
Full Revised Code
import UIKit import CoreData struct JsonData { var nameS: String var usernameS: String init(name: String, username: String) { self.nameS = name self.usernameS = username } } class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext var iteamsArray = [JsonData]() override func viewDidLoad() { super.viewDidLoad() // Load local Core Data data first so the table shows content immediately fetchDataFromCoreData() // Then attempt to download fresh data (updates local storage if successful) downloadJson() } // MARK: - Core Data Fetch Logic func fetchDataFromCoreData() { do { let fetchRequest: NSFetchRequest<Details> = Details.fetchRequest() let details = try context.fetch(fetchRequest) // Clear old data before repopulating iteamsArray.removeAll() // Map Core Data objects to your JsonData struct for detail in details { guard let name = detail.name, let username = detail.username else { continue } iteamsArray.append(JsonData(name: name, username: username)) } // Update UI on main thread (required for all table view changes) DispatchQueue.main.async { self.tableView.reloadData() } } catch { print("Failed to fetch data from Core Data: \(error.localizedDescription)") } } // MARK: - JSON Download & Core Data Update func downloadJson(){ let urlStr = "https://jsonplaceholder.typicode.com/users" guard let url = URL(string: urlStr) else { print("Invalid URL provided") return } URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in // Handle network failures - just stick with existing local data if let error = error { print("Download failed: \(error.localizedDescription)") return } guard let respData = data else { print("No data received from server") return } do{ let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [[String: Any]] // Delete old Core Data entries to avoid duplicate user records let deleteRequest = NSBatchDeleteRequest(fetchRequest: Details.fetchRequest()) try self.context.execute(deleteRequest) // Insert new downloaded data into Core Data for items in jsonObj { guard let nameJson = items["name"] as? String, let usernameJson = items["username"] as? String else { continue } let coreDataEntry = Details(context: self.context) coreDataEntry.name = nameJson coreDataEntry.username = usernameJson } // Save changes to local storage try self.context.save() // Refresh table view with the updated data self.fetchDataFromCoreData() } catch { print("Data processing error: \(error.localizedDescription)") } }).resume() } } // MARK: - TableView extension ViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return iteamsArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "JsonCell", for: indexPath) as! JsonTableViewCell let aData = iteamsArray[indexPath.row] cell.labelName.text = aData.nameS cell.labelUsername.text = aData.usernameS cell.selectionStyle = .none return cell } }
Key Improvements Explained
- Local Data First: In
viewDidLoad(), we callfetchDataFromCoreData()immediately so the table displays stored content right away—even if the device is offline. - Reusable Fetch Method: The dedicated
fetchDataFromCoreData()method handles all local data retrieval and mapping to yourJsonDatastruct. We reuse this both on startup and after downloading fresh data to keep logic consistent. - Prevent Duplicates: Before inserting new JSON data, we delete old Core Data entries using
NSBatchDeleteRequest—this stops your local storage from getting cluttered with duplicate users. - Robust Error Handling: We added guards for invalid URLs, missing data, and network errors. If the download fails, the app gracefully falls back to existing local data.
- Main Thread Safety: All table view reloads run on the main thread, which is mandatory for UI updates in iOS.
Extra Tips
- For explicit network status checking, use
NWPathMonitorto detect offline status and show a user-friendly message (like "No internet connection") when needed. - In production code, avoid force-casting
AppDelegateto access the Core Data context—use a dependency injection pattern for safer, more maintainable code.
内容的提问来源于stack exchange,提问作者Swift
相关产品推荐
相关产品推荐

