Swift package manager generate Xcode project while maintaining group structure - swift

Is it possible to maintain a group structured hierarchy in Xcode when generating from the swift package manager? Every time I run:
swift package generate-xcodeproj
I lose any group (not folder, which works fine) structure I had. I regularly like to have some level of visual organization that is not visible to the code (i.e. groups as opposed to folders) while programming in Xcode.

I believe that what you want is to organize your sources as follows (based on the follow up comment):
Foo/Package.swift
Foo/Sources/Foo/Living.swift
Foo/Sources/Foo/Specifies/Bird.swift
Foo/Sources/Foo/Specifies/Fish.swift
Foo/Sources/Foo/Specifies/Human.swift
Note that the important bit here is that if you want to use subdirectories, you have to ensure that your code is all nested one level down inside of Sources. This is the convention used when one package declares multiple targets, and it is required if you want to use nesting for sources. See the source layouts section in the reference.
If you use this layout, then with the latest Swift package manager (available via swift.org) the generated Xcode project will have the group structure I believe you want.
This is something we know is confusing right now, and we are evaluating how best to improve things.

Related

What is the difference between package and project in Eclipse?

I don't really understand what the point of having a package is. Every Class is kept in a different file, so what's the point of using different packages in a single project?
An Eclipse project has nothing to do with Java. It is a feature of Eclipse to organize and configure your different projects.
A Java package is a language feature of Java. You can use them to structure your project and control visibility between different classes. This becomes necessary even in relatively small projects, which already might have a few hundred classes. I suggest you look for a basic tutorial on what a Java package is and what it can do. To give you a headstart, here is what the official documentation has to say about the purpose of bundling related classes in a package:
You should bundle these classes and the interface in a package for several reasons, including the following:
You and other programmers can easily determine that these types are related.
You and other programmers know where to find types that can provide graphics-related functions.
The names of your types won't conflict with the type names in other packages because the package creates a new namespace.
You can allow types within the package to have unrestricted access to one another yet still restrict access for types outside the package.
Packages are useful for many things. For example, you could store a set of files that do a given task TASK in a package named task.
Packages are a way for developers to find easily and quickly a file, knowing what the role of the file is.
Whenever your project starts growing, packages are essential.
See this lesson for basic understanding of packages utility.

how do I reference a separate project in xcode 4?

How do I reference another project which has code I wish to leverage in XCode 4. In particular I'm trying to make use of the NSDate extensions from here.
Some notes:
I was assuming I should probably reference rather than trying build a framework
I tried copying the existing "Hello World" xcode project file across into my project, however this didn't seem to work
Do I need to create a new "Target" based on "coco touch static library" option?
Then would I need to Edit the current Product Scheme so that when I build the new target would build
What do I need to do on my project side exactly - should going Add Files, and choosing the extensions Xcode Project File be enough?
thanks
I was assuming I should probably reference rather than trying build a framework
yes, reference and link with it, unless you need only a bit of it. at this stage, separating the bits you want may be an advanced topic (depends on the lib's layout/depends as well). you should prefer to reference and link because it will normally minimize your maintenance time, especially if you use it in multiple projects.
I tried copying the existing "Hello World" xcode project file across into my project, however this didn't seem to work
you don't create a project, you add the library's xcode project to your app or library, set the lib as a dependency, add the library to your search paths if needed, then link with the library.
Do I need to create a new "Target" based on "coco touch static library" option?
no
Then would I need to Edit the current Product Scheme so that when I build the new target would build
no. you configure it as a dependency. you may need to alter the lib's build settings if there is a major conflict, which the linker or compiler would point out.
What do I need to do on my project side exactly - should going Add Files, and choosing the extensions Xcode Project File be enough?
start with the process outlined above.
There is no reason to bring in an actually project. Either you can bring in the source files themselves and you could even use the same exact files instead of copying them if you want. However, if you have more than just a few files, and you don't think you will be changing the code much, then creating a static library would probably be the best option.

XCode: Linking projects inquiry

I have 2 projects and I want to use in the first project, a class (i.e. view controller) of the second. Instead of importing all the files of the second project in the first one, is there a way to link it like a framework or library?
I tried the following unsuccessfully:
Dragged-dropped SecondProject.xcodeproj and checked SecondProject.app as a target
Added it as a dependency project in the first project dependencies
Pointed to the header files by adding in the "Header Search Paths" a path pointing to the second project which I copied in a subfolder of the first project.
When I include "SecondProjectViewController.h" I get no errors but when I try to instantiate it I get the "OBJ C referenced from" error.
Any help is deeply needed and appreciated! =)
F.
As an experienced developer I would suggest not sharing code this way across projects. The simple reason is that changes in one project will then directly effect other projects, often rendering them un-compilable. For example, if you share a controller class and decide to implement a change with a new import, then any project that uses that class will be broken until you open then in xcode and ensure that the imported class is available.
A better method is to compile your first project as a static library or framework. I'd also recommend ensuring that it is version some way. For example, in my projects I create static frameworks and store them in a directory called "v0.0.1", "v0.0.2" etc.
The framework can then be dragged and dropped into a second project to use it. The second project then refers to it via the directory path. The advantage of doing this is that if I then change the first project, the second one if not effected by the changes until I choose to update the frameworks path.
Sharing files between projects will work for small cases, that being 2 or 4 projects, but once you have more than that it rapidly becomes un-manageable.
You have only a few steps to go:
4) in First project, click the disclosure triangle in the Groups and Files section for the Second Project reference. this will display the targets of Second Project.
5) Drag the target reference (e.g., static library) from Second Project to the target in First Project's link phase.
That should clear up all the linker errors for the symbols which exist in Second Project's library. Of course, you'll have to remove those sources (based in second Second) which are compiled and linked from First.
Managing static libraries for huge codebases is dead easy this way (although I prefer the build up to the minute (as well as several build variants), and don't reference archived binaries as Derek does). Learning to minimize changes which break builds takes time to learn. dynamic libraries are a bit different - depending on their distribution, you may want to version (as Derek outlined). It's good to share, but you should put the shared exported symbols in a library, which is a dependency of both apps. Just be careful not to add too much unnecessary objc symbols to the library - objc symbols and their references cannot be stripped from the final executable and they will cause runtime collisions if they appear in two images (dylib, app, static lib) within the same process.
You can add the view controller's files to your 1st project regardless of where they are on disk -- the project will make a reference to their location.

Best practices for MacOS/iPhone library cross compiling

I've build a static library working nice in a Cocoa Touch environment. Now I'd like to compile it also for Cocoa.. Can I have a single XCode project with different sdk targets? Is there some resource out there able to give hints about best the practices in this (and other) sense?
This last two months I have been working on exactly this task ( cross compiling static library for iPhone/Android/Mac OS/Linux/Windows...
It is certainly possible, a nice way, is adding an external xcode project as a target to your first xcode project. So you create a new "Active Configuration" for Mac OS X, iPhone and other platforms that you want to support.
Here, you can find a good tutorial about how to use a secondary Xcode project as a target of your main project to build a static library. It's a cool way because if you debug for example you still have all the symbols of the library, etc.
It can be done but it requires some manual tweaking of the build.
Start with the Xcode Build System Guide.
As an informal way of accomplishing this, you can create two separate projects and add references for exact same set of library source files to each project. Set one project to compile for Cocoa-Touch and the other for Cocoa. If both projects reference the same files, changes made in one project will be automatically reflected in the other. (If you have both projects open, Xcode will complain that the file has been changed by another app but otherwise it won't notice.)
I have a utility class that I continually dump new methods in. I add it to every project and just park methods as I need it. The new methods show up in old projects because the source files are shared across all the projects.

Automate the XCode build settings

I've developed a static library that I'd like to share between XCode projects. I did some reading to learn exactly how to include this library as a binary dependency so that it runs on both the device and the simulator and that lead to a couple of manual steps which I'd now like to automate. Overall I'd like to be able to release new versions of my library and have a simple upgrade process for any project using the older version. Currently that process consists of deleting and/or copying the new binary files over the original location, deleting copying over new header files. The initial install consists of the same two steps along with additional project/target level configuration to set conditional linker flags based on the target SDK. Is there a way this could be automated? I mean I know I could do something like write an Applescript to do the heavy lifting but how? Has anyone ever automated xcode build settings via applescript? How would I call into XCode via Applescript? Are there any other alternatives? Is there a better way to maintain binary level dependencies?
Update
I'm looking to maintain a binary level dependency where project A depends on a static library created by project B. Something similar to a framework that can be included into an XCode iPhone project easily. After building "B" I want something that can practically be dropped into and project including A. While I am becoming aware of all the procedures around leveraging such a dependency I am looking for some solutions to soften up all of the rough edges.
Add a custom build script through Xcode:
select your target under the Targets group on the left
select Add -> New Build Phase -> New Run Script Build Phase
double click on the new Run Script item underneath your target
this allows you to write a shell script, accessing most of the Xcode environment variables related to the current build, e.g. $BUILT_PRODUCTS_DIR
if you check the "Show environment variables in build log" and view the detailed build output you can see all the variables available.
Have a Google search and you'll find lots of examples, e.g. section 20.3 here etc.
If you are using Subversion I believe you can use SVN externals to specify which particular version of your library to use.
You just have to drag & drop your library project in your project. xCode will dot the rest...
Regards,
Thierry