Moving source files without XCode in OS X

So I never programmed for OS X before swift and one thing that surprised me was that moving a file directly from finder made my project stop compiling. I had to open the project in XCode (I was using AppCode before but it wasn't letting me move a file to a subdirectory) and move the file from there.

I don't know much OS X but from an outsider's perspective this behavior is really surprising. I suspect that in Ubuntu you can just drag and drop from the file explorer and it can still resolve the relative imports, so would it be possible to make it behave like this in OS X too? I see this surprising (and annoying) a lot of people coming from Python, Java, Kotlin etc.

I'm not an expert in the way that Xcode works, but from my experience I think that Xcode keeps track of the files used in a project. So if you delete a file from Finder Xcode will recognise that and make the file representation (the file as shown in Xcode) in the Project Navigator semi-transparent like a 'disabled-state'. So for your project to compile you need to delete the file from Xcode as well. To add a file you have to drag it into the Project Navigator and Xcode will include it in the source files.

1 Like

Thanks @filip-sakel, I found out the hard way unfortunately. The problem is even if you never use XCode and compile your application in the console, moving a file manually will break everything and require you to open XCode to fix it. Since Swift is no longer just OS X specific this is a little strange to me.

For those of use who just want to do Swift server side development and aren't interested in XCode is there any chance swift will be able to resolve imports by path instead at some point?

I think people doing cross platform and server side Swift typically use SPM to manage their project and generate an Xcode project from SPM, rather than managing one directly. That way it's never out of date, even if SPM's Xcode project's are noisy. So there's no need to resolve imports by path, as a functional SPM package description should allow everything to build automatically.

1 Like

Can you be a little more specific about what you are doing? How are you compiling?

You don't need to use Xcode at all. If you Xcode (maybe Xcode), they maintain lists of files and their paths in their project info that is used to generate the commands to do the actually compile and link. But, you can invoke the compiler directly in the command line. Do a "man swift" or "man swiftc" to see the command line options. Pay particular attention to the "-I ('eye')" option. These specify the paths where swift will look for modules when importing.

If you want to use an IDE based solution like Xcode, AppCode, VSCode, Visual Studio on Windows, etc., they all have project infrastructures that have to be kept synchronized with the layout of the files. Doesn't matter whether you are using macOSX, Windows, or Linux. And, xcodebuild is based on an Xcode project being synchronized correctly.

1 Like

maybe AppCode

I wanted to do a server side project but CLion doesn't work on OS X and sourcekit lsp is still in beta so I used Appcode. Then I decided to refactor my project by adding a new folder and moving a source file inside. For starters Appcode forced me to choose between a folder group or something else (both OS X specific), then it refused to move my file into that folder. I decided I'd just do it in finder, then when I tried to run my project from AppCode it didn't compile until I opened my project in XCode, deleted my file and created it from within XCode.

From your responses I'm guessing it's not really a swift language problem, but more like a side effect of swift tooling assuming you're working on an iOS/OS X specific project and trying to maintain compatibility with XCode? In that case I'm guessing this would be solved when Swift 5.1 comes out with lsp integrated in the toolkit so we can use it easily in VS Code etc. Any idea on approximately when that may happen?

Thanks.

I pretty much use Xcode for everything since I do everything on my Mac, for fun, and don't really care about Linux, Windows, etc., and Xcode is free. This is all to say that what's happening in AppCode, and its relation to Xcode, I'm pretty fuzzy about. However, it does sound like issues that can arise with Xcode if you are not careful about how you use the Finder or command line terminal commands to manipulate file contents external to the IDE's command set. I don't think its a problem specific to Swift, you can run into the same problem with C, C++, et al.

I wouldn't count on SourceKit-LSP being the silver bullet. Like I said, it sounds like an IDE issue, not a language or language tooling issue.

Missing files are shown in red in the file list in Xcode. To refind a missing file you can simply delete it and re-add it. Also, there is a file navigator pane on the right side that lets you re-find it by with a choose-file dialog. Also, note that Xcode stores the location of the file as a relative path or absolute path. You almost always want to use the relative path choice.

While you might want Xcode to just find the file at build time this might not work well if there are multiple files with the same name in different folders. Different languages that Xcode supports may handle multiple files with the same names in different ways.

Renaming files in Xcode can be done easily using the Refactor-rename menu or simply editing the file name in the file list. It will update your git repo as part of that. But moving files is more cumbersome. Sounds like a feature request.

That's all well and good for you, but from listening to Chris Lattner talking I'm sold on the idea that Swift can be so much more than iOS. This is why I decided to give it a try in a few console apps. I have no interest in XCode or iOS/OS X development and the community should be ready for a lot more people like me if Swift starts getting more popular on server side.

Which is exactly why sourcekit-lsp would help a lot. We could start using any IDE and I suspect communities like VS Code would be a lot more interested in improving the dev experience for server side than keeping XCode conventions/compatibility.

@phoneyDev thanks but I don't really care about Xcode. I just want to build console apps that work on Linux and OS X using Swift because the language looks interesting to me. There aren't a lot of options right now on OS X for this, basically just XCode and AppCode, which I have found kind of wonky and also needs me to open Xcode for things like moving files.

It was good to learn it's not a Swift on iOS thing though, so the language doesn't need changing, we just need better tooling for server side devs (which I'm sure is already being worked on).

You can also go old-school, which works just fine, especially if you trying to build console apps. 'swift -o <input files' works just fine. Use lldb instead of gdb.

1 Like

And, I don't do iOS. Mac OSX/Unix utilities (command line apps), using Xcode and old-school, when necessary. Xcode builds command line apps quite nicely.

I bet it does, and I have nothing against XCode I'm just not comfortable in it. I spent a lot of time customizing Jetbrains IDEs to be efficient (eg: custom shortcuts, VIM mode + .ideavimrc etc.). Not sure if the same can be replicated in Xcode but if I'm going to invest the time to configure another editor it might as well be something that can be useful with other languages and OSs like VS Code.

I'm ok with going old school and using the command line to build projects, but I'd still like a good cross platform IDE/editor with good linting and autocomplete for the editing part.

I use Xcode for its syntax colouring, etc. but I find its .xcodeproj files extremely redundant and annoying. I factor out as much as possible into Swift packages, and in that setting Finder is the single source of truth. When I want to move a file, I close Xcode, move the file with Finder, then regenerate the Xcode project (swift package generate-xcodeproj) and open it anew. For someone not using Xcode in the first place, that would reduce to a single step: just moving the file with Finder.