69385

Locate source project directory in Swift from compiled code

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?

Answer1:

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) }

<img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/O6xhX.png" alt="enter image description here">

Answer2:

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:

<img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/cM4gH.png" alt="steps to add a macro">

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

<hr>

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:

<img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/ZGy2G.png" alt="steps to add copy files phase">

Then the path to the file will be:

let path = NSBundle.mainBundle().pathForResource("ViewController", ofType: "swift")

Recommend

  • How to transfer Nifti file into .mat Matlab file?
  • How Do I Resolve “does not denote a properly accessible directory” Exception with UNC Path?
  • Is is possible to use joomla 3 modules on joomla 2.5?
  • Is there a way with MIDL to turn off C-style headers generation?
  • Sun.security couldn't find after upgrading Java
  • yarn hadoop 2.4.0: info message: ipc.Client Retrying connect to server
  • Using Python objects in C++
  • Find the associated program to open a file using Java
  • How to filter entities that are deleted using linq to entities
  • C# DynamicLinq where clause with Any()
  • Finding javafx jar file for windows
  • Change Divider Color Android DatePicker Dialog
  • Google App Engine - SSL InsecurePlatformWarning
  • Google OAuth2 for an web application hosted behind NAT (intranet server without public IP)
  • Calling a constructor through reflection in scala 2.10
  • WCF service runs in Debug mode but not in Release
  • What is the Linux Equivalent of Kernel32.dll?
  • phpmailer - How to verify a sent email arrived at its destination
  • CS1703: In Xamarin.Droid, should I use the .Net Standard windowsruntime.dll located in Mono.Framewor
  • How do I add a File Type Association in a Windows Phone 8.1 app manifest?
  • runtime error when linking ffmpeg libraries in qt creator
  • Ruby on Rails App deployed to heroku showing “We're sorry, but something went wrong”
  • Detecting null parameter in preprocessor macro
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • Create DicomImage from scratch using Dcmtk
  • Combining SpatialPolygonsDataFrame of two neighbour countries
  • How to do unit test for HttpContext.Current.Server.MapPath
  • Excel - Autoshape get it's name from cell (value)
  • Check if a string to interpolate provides expected placeholders
  • Does CUDA 5 support STL or THRUST inside the device code?
  • Shallow update not allowed (git > 1.9)
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • Why winpcap requires both .lib and .dll to run?
  • RestKit - RKRequestDelegate does not exist
  • How do I rollback to a specific git commit
  • Traverse Array and Display in markup
  • Revoking OAuth Access Token Results in 404 Not Found
  • How does Linux kernel interrupt the application?
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • reshape alternating columns in less time and using less memory