首页 > 解决方案 > 如何使用核心数据离线显示 Json 数据

问题描述

在这里,我创建了带有 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
  }
}

标签: jsonuitableviewcore-dataswift3

解决方案


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

var iteamsArray = [Details]()

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

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
  }

推荐阅读