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

Swift应用编译正常但JSON内容无法在IndexViewController显示求助

Swift应用无法加载JSON内容到IndexViewController的问题

我是Swift编程新手,应用可正常编译,但无法读取JSON文件中的内容,IndexViewController无法展示该内容。

IndexViewController部分代码

class IndexViewController: UIViewController,  UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate{
    
    @IBOutlet weak var indexTableView: UITableView!
    @IBOutlet weak var bookmarkButton: UIBarButtonItem!
    
    // BookViewModel的初始化方法负责解码JSON文件并设置chapters属性
    var book: BookViewModel = BookViewModel()
    var chapters: [ChapterViewModel] = [ChapterViewModel]()
    var managedObjectContext: NSManagedObjectContext!
    
    var hasUserTappedOnBookmarkWidget: Bool = false
    
    let searchController = UISearchController(searchResultsController: nil)
    var filteredChapters: [ChapterViewModel] = [ChapterViewModel]()
    var chapNumberAndSearchTextRangeList: [Int: [ChapterViewModel]] = [Int: [ChapterViewModel]]()
    var searching = false
    lazy var workItem = WorkItem()
    
    private var userClickedChapter: ChapterViewModel?
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        chapters = book.chapters
        setNavBarLargeTitleProperty()
        
        // 处理导航栈切换时的表格选中状态动画
        if let selectedIndex = indexTableView.indexPathForSelectedRow {
            
            let coordinator = self.transitionCoordinator

            if coordinator != nil {
                coordinator?.animate(alongsideTransition: { (context) in
                    self.indexTableView.deselectRow(at: selectedIndex, animated: true)

                }, completion: { (context) in

                    if context.isCancelled {
                        self.indexTableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
                    } else {
                        self.indexTableView.deselectRow(at: selectedIndex, animated: true)
                    }
                })
            } else {
                self.indexTableView.deselectRow(at: selectedIndex, animated: true)
            }
        }
        
        // 用户点击小组件时直接跳转到书签页面
        if hasUserTappedOnBookmarkWidget {
            performSegue(withIdentifier: "goToBookmarks", sender: self)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置表格的数据源和代理为当前控制器
        indexTableView.dataSource = self
        indexTableView.delegate = self
        
        indexTableView.register(UINib(nibName: "IndexCell", bundle: nil), forCellReuseIdentifier: "customIndexCell")
}

排查与解决步骤

1. 修复表格不刷新问题

现有代码中,viewWillAppear内将chapters赋值为book.chapters后,未调用表格刷新方法,导致数据更新后界面无变化。添加reloadData():

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    chapters = book.chapters
    indexTableView.reloadData() // 新增:刷新表格展示最新数据
    setNavBarLargeTitleProperty()
    
    // 剩余代码保持不变...
}

2. 排查BookViewModel的JSON解码逻辑

根据注释,BookViewModel的初始化方法负责JSON解码,需确认以下几点:

  • 文件存在性:确保JSON文件已添加到Xcode项目,且勾选了对应Target的Membership(在文件检查器的Target Membership区域)。
  • 路径获取正确性:检查是否正确获取JSON文件路径,示例代码:
    guard let url = Bundle.main.url(forResource: "你的JSON文件名", withExtension: "json") else {
        print("无法找到JSON文件")
        return
    }
    
  • 错误捕获与日志:在解码流程中添加错误捕获,便于定位问题:
    do {
        let rawData = try Data(contentsOf: url)
        let bookModel = try JSONDecoder().decode(Book.self, from: rawData)
        self.chapters = bookModel.chapters.map { ChapterViewModel(chapter: $0) }
    } catch {
        print("JSON解码失败:\(error.localizedDescription)")
        print("错误详情:\(error)")
    }
    
  • 模型结构匹配:确认Book、Chapter等模型结构体的属性名称、类型与JSON结构完全一致,若有差异需使用CodingKeys自定义映射关系。

3. 验证UITableView数据源方法

确保表格数据源核心方法正确返回数据:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? filteredChapters.count : chapters.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customIndexCell", for: indexPath) as! IndexCell
    let chapter = searching ? filteredChapters[indexPath.row] : chapters[indexPath.row]
    // 根据ChapterViewModel的属性设置cell内容,例如cell.titleLabel.text = chapter.title
    return cell
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:01:23