You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用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 call fetchDataFromCoreData() 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 your JsonData struct. 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 NWPathMonitor to detect offline status and show a user-friendly message (like "No internet connection") when needed.
  • In production code, avoid force-casting AppDelegate to access the Core Data context—use a dependency injection pattern for safer, more maintainable code.

内容的提问来源于stack exchange,提问作者Swift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:00:31