Issue opening file in swift - swift

I am trying to read text from a file and I am currently using this statement to read from a file.
When I try to print the path it shows 'nil' and I am not sure why it is not opening the file since it prints the else statement. Can someone tell me how I can go about doing this possibly another way?
if let path = Bundle.main.path(forResource: "knapsack", ofType: "txt")
{
print("File opened")
}
else
{
print("failed to load file from bundle")
}

The solution that worked for me was to add the text file in the product path that is located in Library -> Developer -> Xcode -> Derived Data -> "Your Project" -> Build -> Products -> Debug.
I added the file to this path and this solved issue and had no issue opening the file. I guess Xcode has two different paths that needs to have a file added.

1- create a file named knapsack.txt
2- drag the file to project and select copy
3- reference the file as you currently do
see demo here readFile

Related

Get path of file from a SubGroup in project with Swift 5

I want to access the path of plist file
I am accessing path with following line
I can access when file is in root folder with following line
let filePath = Bundle.main.path(forResource: Constants.googleServiceFileName, ofType: "plist")
but when i move files in sub group and use following code its return nil
let filePath = Bundle.main.path(forResource: Constants.googleServiceFileName, ofType: "plist",inDirectory: "Firebase")
but it's return nil ..
The group in which you keep a resource in Xcode is not necessarily related to its final location in the bundle. Your file is probably still in the top level Resources directory.
If you want to be completely sure where the build puts your file, look for the build log in the Report Navigator, locate the "Copy " line and expand it using the button at the right hand edge. That will tell you exactly where it is.
In the above, I have an Excel spreadsheet in the group testData. You can see that the build has put it in the top level Resources directory.

Bundle.main.url not finding my .obj file in Xcode

I am trying to load a .obj file into Xcode so I can load it using ModelIO.
I got a .obj file, along with a .model and .mtl file, from a website offering free 3D models. (unfortunately I can't remember the name, but I'm sure it's not important) I placed all 3 files into Assets.xcassets.
Then I use the following code to try and load the file. The OBJ file is specifically called "car.obj":
let modelURL = Bundle.main.url(forResource: "car", withExtension: "obj")!
It should be returning a URL that I can use to create an MDLAsset with, but if I try to build the app it just shows the following error:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an
Optional value
Which implies that the file was not found, according the Apple's documentation. This leads me to believe I haven't imported the file properly, or I have a corrupt file. Any ideas?
No need placed to Assets.xcassets. Try placed into project folder. Just like onimage

Bundle.main.path does not find text file added in project

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?
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)
Create a Swift file in your project that you can use to access the data (mine was Recipe.swift)
Drop your CSV into xcode (ignoring target membership - just for convenience (mine was Recipe.json))
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.
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:
Remove the reference of the file
Adding it again on Xcode
Compile and smile while you cry with those Xcode bugs :)

How to get the app list as displayed in Finder "Open in app" dialog for target file format (or file)?

I need to get list of the apps which compatible with a specific file format ( the same as displayed in Open With in Finder for a specific file).
At first tried function "LSCopyAllRoleHandlersForContentType" but in return not all apps ( often completely empty list). Programs appear in this list only if at least once in Finder make them the default for the file format.
Then I tried to get info about file associations formats from Info.plist of applications (using "CFBundleDocumentTypes" key). But for example for "png" I get only Browsers & no applications as Sketch, Skitch,Photoshop and etc.
Maybe I missing something...Thanks in advance.
Probably because your path was invalid:
// don't include file://
let url = NSURL.fileURL(withPath: "file:///Users/xxx/Desktop/public.html")
This works for me:
let url = URL(fileURLWithPath: "/Users/xxx/Desktop/public.html") as CFURL
if let applicationURLs = LSCopyApplicationURLsForURL(url, .all)?.takeRetainedValue() {
print(applicationURLs)
}

Getting path for resource in Command Line Tool

I'm trying to get the path of a resource in a Command Line Tool in Xcode (8 beta 2). Here's what I've got:
The resource, file.xyz, has been dragged into the project and the target membership matches the main project.
Under Build Phases -> Copy Files, the destination is set to "Resources" and the subpath is empty. "Copy only when installing" is unchecked and file.xyz is listed in the table below.
In my main.swift file, I have the following code:
guard let filePath = Bundle.pathForResource("file",
ofType: "xyz",
inDirectory: "Resources") else{
fatalError("Could not find file")
}
The fatalError is triggered every time. Any ideas? I understand that Command Line Tools don't have an application bundle and that's why the resource is being copied into the Resources folder instead, but my inDirectory argument is a bit of a wild guess… Thanks for reading.
EDIT: My primary goal is to access a resource file (text file, in this case) from a CLT—I'm not attached to this specific way of doing it, so if there's an alternate approach that's great too!
With Xcode 13.2 and Swift 5, I had same issue: I've dragged a JSON file into my Command Line Tool project and was not able to use it directly in my code. As CLT does not seems to have a Bundle, I have found a workaround.
I have created a struct with only a static let property containing my JSON as string:
struct CategoriesJSON {
static let string = """
... my JSON is here as plain text ...
"""
}
Now I can use it by simply call: CategoriesJSON.string.
I know it's a bit ugly, but now my JSON is in my project as I needed.
As a workaround, you can use the absolute path of the source file
For example if on iCloud drive :
let path = "/Users/myName/Library/Mobile
Documents/com~apple~CloudDocs/myDirectory/file.xyz"