Reputation: 535
I want to find the directory of my uncompiled source code (because I want to count the lines of it) in my own swift project.
let projectRepo = "/Users/tombrown/Workspace/SwiftGolf" // <-- I want this programmatically
let path = "\(projectRepo)/SwiftGolf/Golf.swift"
var fileContents = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)
I've found the compiled location with NSBundle.mainBundle().bundlePath
, but it doesn't contain the uncompiled code. Any thoughts? Maybe there's a way that I could write a temporary file during the build process?
Upvotes: 3
Views: 5388
Reputation: 5249
The challenge is getting swift to infer location at runtime vs compile time. The arguments in xcode suggestion works well and can be accepted as solution. I couldn't use this approach because I'm using SPM without xcode. Another approach could be to use this library https://github.com/JohnSundell/Files
in you Package.swift
dependencies: [
.Package(url: "https://github.com/JohnSundell/Files.git", Version(1,8,0))
]
then in your code
import Files
let projectRepo = "\(Folder.home.path)/gitWorkspace/SwiftGolf"
do {
let model = try Data(contentsOf:URL(fileURLWithPath: "\(projectDir)/\(modelFile)"))
}catch {
print("error: \(error)")
}
another option is CommandLineKit / xcode arguments
import CommandLineKit .
let cmdLine = CommandLineKit.CommandLine() .
let file = StringOption(shortFlag: "f",
longFlag: "file",
required: true,
helpMessage: "The file you're trying to parse") .
cmdLine.addOptions(file)
do {
try cmdLine.parse()
print(file.value!)
} catch {
print("error: \(error)")
exit(-1)
}
Upvotes: 2
Reputation: 1797
As adding source files to Build Phases > Copy Bundle Resources
doesn't work and to have more flexibility, I recommend to use a little tiny bit of Objective-C.
In the project's Build Settings
add the following line:
and then if your project already has a bridging header the const will become available automatically from Swift
do {
let path = "\(PROJECT_DIR)/Test/ViewController.swift"
let source = try String(contentsOfFile: path)
print(source)
} catch {
print("Error handling goes here")
}
If the project doesn't have a bridging header then it's possible to make Xcode to add one by adding a new Objective-C class to the project and then Xcode will ask about the bridging header.
EDIT:
Also of course bridging header can be added manually, by adding a new header file to the project, and then setting its path to the "Objective-C Bridging Header" in project's Build Settings.
Usually the PROJECT_DIR macro will not be available to Swift code automatically, in the bridging header add:
@import Foundation;
static const NSString *kProjectDir = PROJECT_DIR;
END EDIT
If you are fine with readonly access to the files, you can make Xcode to copy the source files into the app's resource folder by adding a custom script or a Copy Files
Build Phase like on the image:
Then the path to the file will be:
let path = NSBundle.mainBundle().pathForResource("ViewController", ofType: "swift")
Upvotes: 1