【问题标题】:Swift, fetch TableView from JSON and save it into arraySwift,从 JSON 中获取 TableView 并将其保存到数组中
【发布时间】:2020-11-11 10:08:27
【问题描述】:

我在这里尝试做一些简单的事情,但由于我是初学者,所以我有点挣扎。 所以基本上我有一个 JSON 文件链接,用于用 2 个部分填充我的 tableview。每个单元格都有一个“收藏按钮”。 我尝试了很多方法来使用 UserDefault 保存我的数组,但没有成功。 我希望达到的目标:

  • 按下“收藏按钮”时,我希望将单元格移动到其他部分
  • 使用 UserDefault 保存和检索这 2 个数组

我愿意听取任何建议以及任何其他不同的方法,因为我确信有更好的方法。 我将在这里上传一些代码,以及 Git 中完整项目的链接,以便您更好地检查 (https://github.com/Passeric/UserTableview.git)

非常感谢任何帮助。

我正在使用的 JSON:

    {
  "User": [
    {
      "Name": "John",
      "Age": "34"
    },{
      "Name": "Sara",
      "Age": "19"
    }.......]}

我的结构:

class User: Codable {
    let user: [UserDetails]

    enum CodingKeys: String, CodingKey {
        case user = "User"
    }
    init(user: [UserDetails]) {
        self.user = user
    }
}

class UserDetails: Codable {
    let name: String
    let age: String

    enum CodingKeys: String, CodingKey {
        case name = "Name"
        case age = "Age"
    }

    init(name: String, age: String) {
        self.name = name
        self.age = age
    }
}

还有我的 ViewController:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    

    var arrayDefault = [UserDetails]()
    var arrayFavourite = [UserDetails]()
    var sec: [Int:[UserDetails]] = [:]
    var Default = UserDefaults.standard

    
    @IBOutlet weak var myTableview: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.myTableview.dataSource = self
        self.myTableview.delegate = self
        
        DownloadJSON()
        
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        sec = [0 : arrayFavourite, 1 : arrayDefault]
        return (sec[section]?.count)!
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let dataRef = arrayDefault[indexPath.row]
        let cel: MyCell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
        cel.NameLabel.text = dataRef.name
        cel.AgeLabel.text = dataRef.age
        
        let imgFav = UIImage(systemName: "star")
        let b = imgFav?.withRenderingMode(.alwaysOriginal)
        cel.FavButton.setImage(b, for: .normal)
        
        return cel
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    }
    
    func DownloadJSON() {
            let urlll = URL(string: "https://pastebin.com/raw/Wufivqmq")
            guard let downloadURL = urlll else { return }
            URLSession.shared.dataTask(with: downloadURL) { data, urlResponse, error in
                guard let data = data, error == nil, urlResponse != nil else {
                    print("something is wrong")
                    return
                }
                print("downloaded")
                do
                {
                    let decoder = JSONDecoder()
                    let downloadeduser = try decoder.decode(User.self, from: data)
                    self.arrayDefault.removeAll()
                    self.arrayDefault.append(contentsOf: downloadeduser.user)
                    DispatchQueue.main.async {
                        print("data saved")
                        self.myTableview.reloadData()
                    }
                } catch {
                    print(error)
                }
            }.resume()
    }
    
    @IBAction func RefreshButton(_ sender: Any) {
        // Here i wish to refresh the table view (so the current saved array) with the updated JSON
        // For example if i update the "Age" in the original JSON
        // But i don't want to lose the user preference for the "Favourite"
    }
    
    
}

如您所见,这没什么大不了的,但我不知道如何正确保存和检索数组,然后将单元格(通过索引路径)移动到另一个数组。 这是完整项目的链接:https://github.com/Passeric/UserTableview.git 再次感谢任何愿意提供帮助的人。❤️

【问题讨论】:

    标签: ios arrays swift xcode uitableview


    【解决方案1】:

    我会做一些改变:

    1. 清理您的数据模型。目前,您将数据存储为两个数组和一个字典。每种方法都有一些小的优点和缺点,但在总体方案中,使用哪一种并不重要,只需选择一种即可。就个人而言,作为初学者,我会使用两个数组。
    2. 不要更改数据源中的数据模型。目前您正在tableView:numberOfRowsInSection 函数中创建sec 字典。如果您想继续使用sec,请在最初加载数据的同时创建它。或者,如上所述,完全删除 sec
    3. 假设您进行了上述更改,将用户移动到收藏夹部分就像从默认列表中删除用户,将其添加到收藏夹列表中,并告诉列表数据已更改一样简单:李>
    func makeFavorite(index:IndexPath) {
        let user = arrayDefault[index.row]
        arrayDefault.remove(at: index.row)
        arrayFavourite.append(user)
    
        //This updates the entire list.  You might want to use moveRow(at:to:) in order to animate the change
        tableView.reloadData()
    }
    
    1. 在将数据模型转换为 json 或从 json 转换时,您已经通过遵守 Codable 完成了大部分工作。从 json 加载:
    if let jsonData = UserDefaults.standard.string(forKey: "userKey").data(using: .utf8) {
        let decoder = JSONDecoder()
        if let user = try? decoder.decode(User.self, from: jsonData) {
            //Do something with user here...
        }
    }
    

    并输出到json:

    let encoder = JSONEncoder()
    if let data = try? encoder.encode(user),
        let jsonString = String(decoding: data, as: .utf8) {
        UserDefaults.standard.setValue(jsonString, forKey: "userKey")
    }
    

    对收藏列表执行相同的操作(使用不同的键)。

    【讨论】:

      猜你喜欢
      • 2017-04-21
      • 2018-06-10
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多