首页 > 解决方案 > 如何将 Json 数据发送到表视图数组?迅速

问题描述

我一直在研究并破坏我的大脑,试图将我的 JSON 数据加载到我的 tableview 中。我尝试将数据放在变量中,并且在打印时可以在控制台中看到数据,但是无法将其推送到我的表格视图中。

我是在数据页面上做错了什么,还是我没有正确访问循环内的数据?

我已经尝试将循环放在 viewdidload 中,但也没有成功。

// ViewController

import Foundation
import UIKit
import SDWebImage

class EntertainmentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var A = EntertainmentApi()
    
    var data = [EntertainmentPageData]()
    var AA = EntertainmentApi().userFeedPosts
    @IBOutlet weak var entPostTableView: UITableView!
   
    
    override func viewDidLoad() {
        
        func showTable() {
            
        }
        entPostTableView.register(EntertainmentViewrTableViewCell.nib(), forCellReuseIdentifier: EntertainmentViewrTableViewCell.identifier)
        entPostTableView.delegate = self
        entPostTableView.dataSource = self
        super.viewDidLoad()
        
        
        DispatchQueue.main.async {
        
        self.entPostTableView.reloadData()
        }
    }
    
    
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let customCell1 = tableView.dequeueReusableCell(withIdentifier: EntertainmentViewrTableViewCell.identifier, for: indexPath) as! EntertainmentViewrTableViewCell
        customCell1.profileDisplayName.text = AA[indexPath.row].postDisplayName
            self.AA.forEach({ (EntertainmentPageData) in
                customCell1.configue(with: EntertainmentPageData.postDisplayName, PostImage: EntertainmentPageData.imageURLString, PostDescription: EntertainmentPageData.postDescription)
            })
                    
                            
        
           
            
 
        return customCell1
            
        
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    func item(for index: Int) -> EntertainmentPageData {
        return data[index] 
    }
    func numberOfItems() -> Int {
        return data.count
    }
}
//Data

import SwiftUI
import SDWebImage

public protocol EntertainmentPagePostItem {
    /// The image for the card.
    var imageURLString: String { get }
    
    /// Rating from 0 to 5. If set to nil, rating view will not be displayed for the card.
    var postDescription: String? { get }
    
    /// Will be displayed in the title view below the card.
    var postDisplayName: String { get }
}

public protocol EntertainmentPagePostDataSource: class {
    /// CardSliderItem for the card at given index, counting from the top.
    func item(for index: Int) -> EntertainmentPagePostItem
    
    /// Total number of cards.
    func numberOfItems() -> Int
}
struct HomePagePost: Codable {
    var displayName: String
    var cityStatus: String
    var displayDescription: String
    var displayImageURL: String
    var lookingFor: String
    var profileImager1: String?
    var profileImager2: String?
    var profileImager3: String?
    var profileImager4: String?
    
}

struct EntertainmentPageData: Codable {
    let postDisplayName: String
    let imageURLString: String
    let postDescription: String?
    
}
public class entPostFly: Codable {
    let postDisplayName, imageURLString, postDescription: String
}
struct eItem: EntertainmentPagePostItem {
    var postDisplayName: String
    var imageURLString: String
    var postDescription: String?
}

public class EntertainmentApi {
    
    var userFeedPosts = [EntertainmentPageData]()
    
    init() {
        load()
    }
    
    func load() {
        
        guard let apiURL = URL(string: "https://api.quickques.com/....") else {
        return
    }
    
        let task: () = URLSession.shared.dataTask(with: apiURL) { Data, apiResponse, error in
            
            guard let Data = Data else { return }
            
            do {
                let entPostData = try JSONDecoder().decode([EntertainmentPageData].self, from: Data)
                self.userFeedPosts = entPostData
                
            }
            catch {
                let error = error
                print(error.localizedDescription)
            }
            
        }.resume()
        
    }
    
    
    func getFeedPosts(completion: @escaping ([EntertainmentPageData]) -> () ) {
        guard let apiURL = URL(string: "https://api.quickques.com/....") else {
        return
    }
    
        let task: () = URLSession.shared.dataTask(with: apiURL) { Data, apiResponse, error in
            
            guard let Data = Data else { return }
            
            do {
                let entPostData = try JSONDecoder().decode([EntertainmentPageData].self, from: Data)
                completion(entPostData)
            }
            catch {
                let error = error
                print(error.localizedDescription)
            }
            
        }.resume()
    
}
    
    
}

class Api {
    
    func getHomePagePosts(completion: @escaping ([HomePagePost]) -> Void ) {
        guard let apiURL = URL(string: "https://api.quickques.com/.....") else {
            return
        }
        
        let task: () = URLSession.shared.dataTask(with: apiURL) { Data, apiResponse, error in
            
            guard let Data = Data else { return }
            
            do {
                let homePostData = try JSONDecoder().decode([HomePagePost].self, from: Data)
                
                completion(homePostData)
            }
            catch {
                let error = error
                print(error.localizedDescription)
            }
            
        }.resume()
       
    }
    
    
    func getImageData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
        URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
    }
    
    
    
}

func getTopMostViewController() -> UIViewController? {
    var topMostViewController = UIApplication.shared.keyWindow?.rootViewController

    while let presentedViewController = topMostViewController?.presentedViewController {
        topMostViewController = presentedViewController
    }

    return topMostViewController
}

标签: iosswiftswiftui

解决方案


首先,您的showTable 内部有一个空函数viewDidLoad- 这什么都不做。大概是你的各种尝试中的一些东西。删除那个。

正如您可能已经解决的那样,您的网络获取操作将异步发生,并且您需要在获取数据后重新加载表视图。

您有一些代码viewDidLoad尝试执行此操作,但它与 fetch 操作无关。它只是在下一个运行循环周期异步调度;这可能仍然是在获取数据之前。

但是,即使数据已被提取,它也不会显示,因为您是在初始化时userFeedPosts从 API 对象的第二个实例分配给的。AA这个数组是空的,并且将保持空,因为 Swift 数组是值类型,而不是引用类型。userFeedPosts更新时,AA会保存原来的空数组。

要加载您需要的数据

  1. 视图加载时启动加载操作
  2. 将完成处理程序传递给加载完成时要调用的加载操作
  3. 使用新数据重新加载表格视图
class EntertainmentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
   
    var data = [EntertainmentPageData]()
    @IBOutlet weak var entPostTableView: UITableView!
    
    override func viewDidLoad() {
        
        entPostTableView.register(EntertainmentViewrTableViewCell.nib(), forCellReuseIdentifier: EntertainmentViewrTableViewCell.identifier)
        entPostTableView.delegate = self
        entPostTableView.dataSource = self
        super.viewDidLoad()
        
        EntertainmentAPI.getFeedPosts { result in 
            DispatchQueue.main.async {      // Ensure UI updates on main queue
                switch result {
                    case .error(let error):
                        print("There was an error: \(error)")
                    case .success(let data):
                        self.data = data
                        self.entPostTableView.reloadData
                }
            }
        }
    }
   
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let customCell1 = tableView.dequeueReusableCell(withIdentifier: EntertainmentViewrTableViewCell.identifier, for: indexPath) as! EntertainmentViewrTableViewCell
        let post = data[indexPath.row)
        customCell1.profileDisplayName.text = data[indexPath.row].postDisplayName
        customCell1.configure(with: post.postDisplayName, PostImage: post.imageURLString, PostDescription: post.postDescription)
        return customCell1   
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
}

public class EntertainmentAPI {
    static func getFeedPosts(completion: @escaping ((Result<[EntertainmentPageData],Error>) -> Void) ) {
        guard let apiURL = URL(string: "https://api.quickques.com/....") else {
        return
    }
    
    let task = URLSession.shared.dataTask(with: apiURL) { data, apiResponse, error in

            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let data = data else { 
                /// TODO - Invoke the completion handler with a .failure case
                return 
            }
            
            do {
                let entPostData = try JSONDecoder().decode([EntertainmentPageData].self, from: Data)
                completion(.success(entPostData))
            }
            catch {
                completion(.failure(error))
            }
            
        }.resume()
    }
}

推荐阅读