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

SwiftUI读取CSV文件报错文件未找到,如何读取并展示数据?

SwiftUI 读取CSV文件失败的解决方法

问题描述

尝试在SwiftUI中读取capitals.csv文件,但运行后仅显示Error file cant be found。当前实现的CSV读取函数及视图代码如下:

读取函数代码

import SwiftUI

extension String{
    //Get the filename from a String
    func fileName ( ) -> String{
        return URL (fileURLWithPath: self).deletingPathExtension().lastPathComponent
    }
    //Get the file extension from a String
    func fileExtension() -> String{
        return URL (fileURLWithPath: self).pathExtension
    }
    
}

func readCSV (inputFile: String, separator: String) -> [String]{
    //Split the file name
    let fileExtension = inputFile.fileExtension()
    let fileName = inputFile.fileName()
    //Get the file URL
    let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let inputFileURL = fileURL[0].appendingPathComponent(fileName).appendingPathExtension(fileExtension)
    //Get Data
    do{
        let savedData = try String(contentsOf: inputFileURL)
        return savedData.components(separatedBy: separator)
    } catch{
        return ["Error file cant be found"]
    }
}

视图代码

struct Test: View{
    
    var data = readCSV(inputFile: "capitals.csv", separator: ",")
    
    var body: some View{
        VStack{
            Text(data[0])
            
        }
}

问题原因

代码错误地将文件路径指向了用户的文档目录(documentDirectory),但capitals.csv作为项目资源文件,实际存储在App的主Bundle中,因此找不到文件。此外,当前的CSV解析逻辑仅简单按分隔符拆分,未处理换行,无法正确解析CSV的行结构。

解决方案

1. 修正文件路径与解析逻辑

将文件路径改为从Bundle中获取,并优化CSV解析格式:

func readCSV(inputFile: String, separator: String) -> [[String]] {
    // 从App主Bundle中获取文件URL
    guard let fileURL = Bundle.main.url(forResource: inputFile.fileName(), withExtension: inputFile.fileExtension()) else {
        return [["Error file cant be found"]]
    }
    
    do {
        let savedData = try String(contentsOf: fileURL)
        // 先按行拆分,再按分隔符拆分每行内容,过滤空行
        let rows = savedData.components(separatedBy: .newlines)
        return rows.compactMap { row in
            let columns = row.components(separatedBy: separator)
            return columns.isEmpty ? nil : columns
        }
    } catch {
        return [["Error reading file: \(error.localizedDescription)"]]
    }
}
  • 返回类型改为[[String]],对应CSV的行、列二维结构,更贴合实际数据格式。
  • 使用Bundle.main.url(forResource:withExtension:)获取资源文件的正确路径。

2. 确保CSV文件已添加到项目Target

选中capitals.csv文件,查看右侧File Inspector,确认Target Membership勾选了当前App的target,确保文件被打包到App Bundle中。

3. 优化视图数据加载逻辑

利用SwiftUI的生命周期方法异步加载数据,避免视图初始化时的同步加载问题:

struct Test: View{
    @State private var csvData: [[String]] = []
    
    var body: some View{
        VStack{
            if csvData.isEmpty {
                Text("Loading data...")
            } else {
                // 示例:遍历展示第一行数据,可根据需求调整为多行展示
                ForEach(csvData[0], id: \.self) { item in
                    Text(item)
                        .padding(.vertical, 4)
                }
            }
        }
        .onAppear {
            csvData = readCSV(inputFile: "capitals.csv", separator: ",")
        }
    }
}
  • 使用@State存储CSV数据,在视图出现时(onAppear)调用读取函数。
  • 增加加载状态提示,提升用户体验。

额外提示

如果CSV包含带引号的字段(如"New York, NY"),简单的components(separatedBy: ",")会拆分错误,此时建议使用成熟的CSV解析库处理复杂格式。

内容的提问来源于stack exchange,提问作者Steven Park

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:20:36