3

I have a command line project in Xcode 9 and I'm trying to read a text file I added to the project via "Add files to...". I'm using the following line to grab the path to the file:

guard let filePath = Bundle.main.path(forResource: "stops", ofType: "csv") else {
        fatalError("Cannot find CSV file")
    }

When I run it, it prints out the fatalError message. I tried adding the text file in the "Copy Bundle Resources" build phase. It still doesn't find the file.

What am I doing wrong?

jscs
  • 63,694
  • 13
  • 151
  • 195
pedroremedios
  • 763
  • 1
  • 11
  • 39
  • Is the text file is added in Bundle, check in Build phase > Copy Bundle Resources option – Joe Oct 29 '17 at 22:18
  • 1
    @Joe OP said **I tried adding the text file in the "Copy Bundle Resources" build phase.** – Leo Dabus Oct 29 '17 at 22:18
  • 1
    Possible duplicate of https://stackoverflow.com/questions/43826866/read-a-file-in-a-macos-command-line-tool-project – Vini App Oct 29 '17 at 23:54
  • Possible duplicate of [Read a file in a macOS Command Line Tool project](https://stackoverflow.com/questions/43826866/read-a-file-in-a-macos-command-line-tool-project) – jscs Oct 30 '17 at 01:40

2 Answers2

1

The issue for me was I have created first a ResponseJSON.swift then rename it to ResponseJSON.json (changed to .json extension) and it was not being detected.

Solution:

  1. Remove the reference of the file
  2. Adding it again on Xcode
  3. Compile and smile while you cry with those Xcode bugs :)
Eironeia
  • 771
  • 8
  • 20
0

Early last year I had this same issue - here is my workaround (and I must stress that this is a work around, hopefully there is another way to do it now)

  1. Create a Swift file in your project that you can use to access the data (mine was Recipe.swift)
  2. Drop your CSV into xcode (ignoring target membership - just for convenience (mine was Recipe.json))
  3. Create a run script phase to load the data from your CSV to into a Swift class:

    set -e
    DATA=$(cat "./MyProject/recipe.json" | base64)
    echo "import Foundation" > "./MyProject/Recipe.swift"
    echo "class Recipe {" >> "./MyProject/Recipe.swift"
    echo "    static let data = \"$DATA\"" >> "./MyProject/Recipe.swift"
    echo "}" >> "./MyProject/Recipe.swift"
    

This generates a class in your Swift file that looks something like:

import Foundation
    class Recipe {
        static let data = "..."
}

And then you can decode Recipe.data when you need to use it.

Of course this isn't a very expandable solution, and I'm sure you can make it better by using lazy initialization, adding the base64 decode directly in the generated class, making paths in the script relative to $SRCROOT etc. This was just my quick solution that allowed me to continue working on the rest of the project.

Max Chuquimia
  • 7,494
  • 2
  • 40
  • 59