I'm trying to read a file in an Xcode app, the file belonging to the app, rather than some user file outside the project directory. I've reduced the problem to the simplest case as follows using the ContentView source file as the one I try to access.
I create a new multiplatform Xcode project (called read
)
It opens showing the ContentView file, which I edit by replacing "Hello, World!"
with printFile()
also including the printFile()
definition. ContentView becomes:
import SwiftUI
func printFile() -> String {
do {
return try String(contentsOfFile: "/Users/my_username/read/read/ContentView.swift")
} catch {
return error.localizedDescription
}
}
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text(printFile())
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I run the project and the window opens with the localized error description
The file "ContentView.swift" couldn't be opened because you don't have permission to view it.
I've tried solutions from duplicate questions (eg here). Some points:
- There's no plist file in this project.
- I've granted Xcode full-disc access.
- The "Compiler for C/C /Objective-C" is already "Default compiler (apple clang)."
- I've change nothing in the project except the
ContentView
file as described above. - I'm running this multiplatform app with My Mac.
startAccessingSecurityScopedResource
shouldn't be necessary, since I'm not even accessing files in 'standard locations,' but only within the project itself.
So how is a project to get access to read its own project files (eg databases, configurations, etc)? Is the behavior above expected behavior?
CodePudding user response:
If the file in question is a resource (like a text file) inside the app bundle (because it is part of the app target), you can read it thru Bundle.main
and url(forResource:...)
.
If it isn't, then you can't read it as an arbitrary file in a fixed location without full disk access or turning off sandboxing.
Note that a .swift
file that is a source file for the app is not in the app; it is compiled to form the app's executable, which is not readable.