How to cope with a large Swift project?

After the iPhone application that I write in Swift becomes quite large (> 150 .swift files + various Objective-C libs), the beginning of Xcode behaves rather badly:

  • every second compilation I get various errors, for example:

    Command failed due to signal: Segmentation fault: 11

  • collecting takes a huge amount of time (> 2 minutes on a MacBook Pro Retina)
  • etc.

I'm just wondering if everyone has the same problems, and maybe someone found a way to reduce this nightmare?

What I have done so far - I divided the project into several dynamic frameworks, which I associate with the main project, this helps reduce compilation time, but introduces some new problems.

I also use iRamDisk to keep the DerivedData folder in RAM and periodically delete all files from it, sometimes it helps with SourceKit crashes.

+52
ios compilation xcode swift
Jan 19 '15 at 19:54
source share
5 answers

The Swift toolchain is still a little rude, you will need to use temporary workarounds until Apple fixes this (see UPDATES )

Here is a list of items you can do to keep your mind going.

Slowness caused by immature Swift compiler

  • Modify your development workflow using Injection for Xcode . After installing the plugin, you can make code changes to your \ device simulator without recompiling. You do not need to hardcode / modify anything in your project. We started using it recently at work, and this has had a huge impact on our side, even if it does not apply to all use cases (for example, you cannot create new functions, you can only modify existing ones).

  • Some specific code constructs that the compiler does not like and takes too much time to compile. The most common problem is that Type Checker slows down compilation time exponentially depending on the number of type checks that need to be performed (more details here for practical examples and here for a detailed explanation). To determine if you are suffering from this problem, you can follow this message, you will collect information about functions that create slowness, using some additional compiler flags. Alternatively, you can use this Xcode plugin to identify the source of assembly slowness.

  • Use dynamic structures wisely where that makes sense. A recompilation of the framework will be performed only when changing one of its Swift files (dynamic frameworks are available only for iOS> = 7).

  • Condensed code in the same files. Reducing the number of Swift files speeds up the compilation process. You can easily achieve this by turning on “Optimization of the whole module”, adding a custom custom flag SWIFT_WHOLE_MODULE_OPTIMIZATION and setting it to YES and at the same time set the optimization level to none (to disable the optimization, which will make it slow) OUTDATED You can use this gist , this is a build script that collapses all your code into "merge.swift". You will need to create a new goal for him, but it's worth a try.

  • Double checking the things listed here (there are a few other considerations because compilation is slow)

  • OUTDATED Try the approach described in this blog , it involves creating a build script that creates the make file. It requires manual intervention in the script assembly (it contains a list of fast files).

  • OUTDATED Try this hack incremental compilation technique

UPDATE: incremental builds introduced in Swift 1.2 (Xcode 6.3)

Finally, Apple introduced incremental builds with Swift 1.2 (shipped with Xcode 6.3). This is not perfect yet, but it is a huge improvement.

From now on, a class is recompiled only when it is changed (or when one of its class, on which it depends, has been changed). However, the compiler still does not understand whether changes to the class are an interface or not. Thus, any change to a class causes a recompilation of this class and all its dependencies.

UPDATE: recompile dependent classes only if changes to the public interface introduced in Swift 2.1 (Xcode 7.1)

Starting with Swift 2.1 (Xcode 7.1), dependent classes are recompiled only when the public interface of the class changes, and not every time it changes. This is especially important for large projects.

Project Configuration (Incorrect) (Non-Swift)

  • Be sure to use "Built-in Active Architecture Only" for "debugging".
  • Make sure you do not add pre-compilation scripts that take too long.
+58
Jan 25 '15 at 10:28
source share

Apple has some tips for speeding up the build of Xcode in Tech Note 2190 . Have you considered creating and precompiling your own structure for outsourcing without changing the Swift modules or some / all Objective-C code?

Delete all lines in Swift.

This SO topic has some good ideas and this blog post suggest

  • stop creating dSYM packages and
  • Avoid compiling with -O4 when using Clang.

Although many of these enhancements are related to Objective-C, I am sure that some of them are still relevant to Swift.

+2
Jan 22 '15 at 23:40
source share

Compiling (re) is a known issue that I am sure will be resolved soon. Some recommendations:

  • Use Objective-C wherever possible - it compiles quickly even if it is part of a Swift project
  • Split code into frameworks
  • Specify types instead of leaving it to the compiler to output them

Again, there is a good chance that this will be fixed in the near future, so it might be better not to make a big investment in rewriting or reorganizing the code at the moment.

+2
Jan 23 '15 at 0:04
source share

you can try:

  • updating the amount of RAM on your computer.
  • If you have multiple .swift files that do things on the same view controller, try condensing them into a single .swift file for each view controller.
  • setting parameters in compilation sources to see if you have duplicates, or if there are any scripts or settings that you can add to speed up its compilation ...

You can also take a look at this one to answer some tips on what you can do to slow down compilation time.

+1
Jan 22 '15 at 23:23
source share

I found that one of the main causes of segmentation errors and slow compilation is hard coding of large arrays and dictionaries, especially when declaring them as global constants and trying to access the values ​​from them from another .swift file. When I store all this data inside plists, these problems disappeared.

+1
Jan 29 '15 at 15:54
source share



All Articles