Organizing Swift Application

I am coming from C# where the recommended approach is to split you application into distinctive functional parts and they show up in Visual Studio as projects. The output would be a library or executable for each project, For example a webservice would have API project ( executable) and a set of libraries: Logic, Model, Migrations etc.
That makes a lot of sense. For example if you try to address a DB Model in your API layer( which you are not supposed to) the compilation fails.

Now I am starting working with Xcode/Swift and am a little confused between internal packages ( which I guess could be considered projects in Visual Studio) and targets. A number of internal resources recommends splitting applications into internal packages but auto generators create one package with several targets. Which one to use? In my case I want to separate Logic and Db Models from the rest of the application.

1 Like

Hi Karamba,

The TLDR is that Packages are similar to an Xcode project or .Net Solution. Swift packages can contain multiple targets (executables and libraries).

If your application is for an Apple platform, you'll most certainly need an Xcode project with at least one target for the main application executable. You can add more targets for static or dynamic libraries, without using swift packages. However, you can move some of these targets into their own packages and store them in different repositories (eg. if you want to reuse a package across multiple applications).

If your application is for command line, or server-side, you can still have an Xcode project but you can also do pretty much everything without it. In this case you would want to have a Package, with different targets for the executable and libraries. You can also move some of those targets to separate packages and add them as dependencies.

Hope that helps.

Heya, fellow dev with a C# background here! I also came into the iOS world from C#.NET wondering how all of this should be organized. Unfortunately, app development doesn't implicitly lead to the same level of modularization that may be enforced by various .NET standards, but that doesn't mean it isn't possible.

To elaborate further on what Eneko mentioned, some other notes:

  1. A Project may contain multiple Targets, and each Target results in a unique Bundle/Module. This means you could theoretically create a new Target for each "separation" of the library you'd like to create. (However, Packages are a better format for library modularization IMO.)
  2. A Workspace may contain multiple Projects and Packages. So right here, you can either separate with one Project and numerous Targets, or by multiple Projects all with on Target.
  3. A Swift Package may contain multiple Products, which are basically "output" Modules that can be consumed by your project (or other projects, if you decide to make your package external).

Basically, all I'm trying to elaborate on is that while .NET has more of a standardized way of separating modules into different projects (or even simply different namespaces), and also has a different level of access control (with the protected keyword coming to mind), there are still ways to achieve what you're looking to do.

Personally, I prefer:

  • Always having a Workspace unless I'm doing command-line (ie. Package-only) development.
  • Having one Project for each "product". (eg. multiple apps in a monorepo should all have their own Project)
  • Shared code within a Workspace should always go into a Package as they are much easier to manage these days than a shared Framework Project. Additionally, managing Target Membership is a nightmare and will lead to unnoticed issues and human error, so I avoid it at all costs.

There are plenty of exceptions to what I've mentioned above, and also probably some things I over-simplified, but if I were helping someone make the move from C#.NET to iOS/Swift development, these are the high-level "project structure" notes I would include.

Given the above info and comparison @karamba, do you have any additional questions or is there anything still unclear?

Terms of Service

Privacy Policy

Cookie Policy