【问题标题】:How to show Json data in Offline using core data如何使用核心数据离线显示 Json 数据
【发布时间】:2026-01-06 10:05:01
【问题描述】:

在这里,我创建了带有 labelName 和 labelUsername 的表格视图, 我已经下载了 Json 数据并将其保存在名为 Details 的核心数据实体中,其中包含属性名称和用户名。 这里的表格视图在网上显示其数据... 但是离线时如何在表格视图中显示获取的数据..

请帮我写代码...

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() {
    downloadJson()
  }

  func downloadJson(){        
    let urlStr = "https://jsonplaceholder.typicode.com/users"
    let url = URL(string: urlStr)

    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in            
        guard let respData = data else {
          return
        }
        guard error == nil else {
          print("error")
          return
        }

        do{
          let jsonObj = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [[String: Any]]

          for items in jsonObj {
            let nameJson = items["name"] as? String
            let usernameJson = items["username"] as? String                    
            let coreData = NSEntityDescription.insertNewObject(forEntityName: "Details", into: self.context) as! Details
            coreData.name = nameJson
            coreData.username = usernameJson

            self.iteamsArray.append(JsonData(name: nameJson!, username: usernameJson!))
          }
          try self.context.save()

            //fetching from core data
          let fetchRequest : NSFetchRequest<Details> = Details.fetchRequest()
          let details = try self.context.fetch(fetchRequest)

          if details.count > 0 {                   
            for detail in details as [NSManagedObject] {                        
              let nameCore = detail.value(forKey: "name")
              let usernameCore = detail.value(forKey: "username")      
            }
          }

          DispatchQueue.main.async {
            self.tableView.reloadData()
          }                
        }
        catch {
          print("catch error")
        }            
      }).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
  }
}

【问题讨论】:

  • 您能否更详细地描述您的问题是什么。
  • 我想在离线时在表格视图中显示用户名和名称,我已从 jsonObj 保存在核心数据中,但在这里我无法将获取的数据附加到 itemsArray 以显示在 tableviw @JoakimDanielson
  • 是的,我明白了,但是您的代码的哪一部分不起作用?您正在执行获取并实现表视图数据源方法。
  • 我无法将获取的 nameCore 和 usernameCore 附加到 itemsArray 以显示在 tableview @JoakimDanielson
  • 当我像 self.iteamsArray.append(JsonData(name: nameCore as!String, username: usernameCore as!String)) 一样追加时。它显示错误在展开可选值时意外发现 nil

标签: json uitableview core-data swift3


【解决方案1】:

首先忘记自定义结构。使用NSManagedObject 类作为数据源数组。

var iteamsArray = [Details]()

viewDidLoad 首先获取数据,如果数组为空,则从网络服务加载它

override func viewDidLoad() {
   let fetchRequest : NSFetchRequest<Details> = Details.fetchRequest()
   do {
       iteamsArray = try self.context.fetch(fetchRequest)
       if iteamsArray.isEmpty { 
           downloadJson()
       } else {
           self.tableView.reloadData()
       }
    } catch { print(error) }
}

downloadJson()替换

self.iteamsArray.append(JsonData(name: nameJson!, username: usernameJson!))

self.iteamsArray.append(coreData)

并删除这些行

//fetching from core data
   let fetchRequest : NSFetchRequest<Details> = Details.fetchRequest()
   let details = try self.context.fetch(fetchRequest)

   if details.count > 0 {                   
     for detail in details as [NSManagedObject] {                        
       let nameCore = detail.value(forKey: "name")
       let usernameCore = detail.value(forKey: "username")      
   }
}

cellForRow 中直接从NSManagedObject 对象中获取值

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.name
    cell.labelUsername.text = aData.userName
    cell.selectionStyle = .none
    return cell
  }

【讨论】: