64

I've installed Xcode 8.0 and converted Swift 2.2 to 3.0 (that process also took a lot of time, I just left my Mac running all night). I have not a big project (about 20 files). I am also using Pods. Indexing of previous Xcode version (< 8.0) worked fast but now, after upgrade, the progress bar is stuck on one position (I am already waiting for an hour).

Things I've tried that didn't help me:

  • Cleaned the DerivedData folder and restarted Xcode
  • Cleaned the project and restarted Xcode
  • Deleted Pods directory with <project>.xcworkspace and then installed again
  • Restarted Mac
  • Tried build project without Pods
  • Reinstalled Xcode
  • Tried on another Mac with cloned project

It is really not cool to make such releases of software when developers have to spend hours on solving such ridiculous problems. It is very disappointing. Any ideas how to fix this?

Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
Danny
  • 3,975
  • 4
  • 22
  • 35
  • Are you able to build it at all? If so, you can use Build Time Analyzer to learn more about what's slowing down the build process. https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode – Robert Gummesson Sep 17 '16 at 13:34
  • @Robert unfortunately it is not building – Danny Sep 17 '16 at 13:35
  • Does the build log show anything? (Click the far right button that looks like a cartoon bubble.) Or anything in the Console app? – Myke Savage Sep 20 '16 at 01:41
  • This worked for me on Xcode 8.3 swift 3.1 - http://stackoverflow.com/a/40497873/1890317 I went from over a minute build to 17 seconds – uplearned.com Mar 30 '17 at 01:01

17 Answers17

53

Go to project settings, then Editor > Add Build Setting > Add User-Defined Setting, and add the following:

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

Adding this flag dropped our clean-build compile times from 7 mins to 65s for a 40KLOC swift project, miraculously. Also can confirm 2 friends have seen similar improvements on enterprise projects.

I can only assume this is some kind of bug in Xcode 8.0

Chris
  • 39,719
  • 45
  • 189
  • 235
  • 2
    Worked for our team too. We are running Xcode 8.0, Swift 2.3 on a codebase that is both Swift and Objective C. – Robert Wagstaff Oct 11 '16 at 02:18
  • @hardik.shah - i have no idea. I couldn't believe it either when it worked. – Chris Oct 15 '16 at 22:45
  • 1
    this took our clean-build time from 6 minutes to 2 minutes! How does this setting differ from the build configuration optimization level and which takes precedence? And how in the world did you discover this? Many thanks – n8tr Nov 11 '16 at 13:13
  • 1
    @n8tr I'm not sure if this takes precedence over the normal WMO setting. A friend discovered it by accident! – Chris Dec 04 '16 at 08:51
  • 6
    No one has mentioned it yet, but this breaks incremental compilation. So while your clean build is now faster, you lose the speed of only having to rebuild a few files at a time when you change one. – Jon Shier Dec 14 '16 at 02:57
  • 3
    This works, but it breaks a number of things that you rely on during development: breakpoints and step through is unreliable, variables are not available when you hit a breakpoint and try to see the content of a variable, command + click to jump to the definition barely works. – Zsolt Apr 16 '17 at 03:54
23

I solved the problem by commenting all files and then removing comments one by one. I found that the problem is still in the array declaration as described here.

I had code like this and project was not indexing:

class {
    var first: String!
    var second: String!
    var third: String!
    var fourth: String!
    var fifth: String!

    func abc() -> [String] {
        var array = [first, second, third, fourth, fifth]
    }
}

I've changed it to this and indexing started working:

class {
    var first: String!
    var second: String!
    var third: String!
    var fourth: String!
    var fifth: String!

    func abc() -> [String] {
        var array = [first]

        array.append(second)
        array.append(third)
        array.append(fourth)
        array.append(fifth)
    }
}
Community
  • 1
  • 1
Danny
  • 3,975
  • 4
  • 22
  • 35
  • 6
    That could be a issue with inferring the type of the array. Instead of using append do that: var array: [String] = [first, second, third, fourth, fifth] – Marco Pappalardo Nov 03 '16 at 16:41
6

I've had the same issue only since upgrading to Swift 3/XCode 8 and it seems to be caused by large array literals.

I was able to fix the issue by adding type annotations to the variables being assigned to the array literal, e.g.

let array: Array<String> = ["1", "2", "3", "4", "5", "6", "7", "8"]

instead of

let array = ["1", "2", "3", "4", "5", "6", "7", "8"]
Ben Simon
  • 121
  • 3
5

I had similar problem and followed this guide to debug : http://irace.me/swift-profiling My problem was i had nil coalescing operator in some strings for example:

let name = "\(someString ?? "")"

and four methods with this were causing 2 min additional building time.

Stefan Nestorov
  • 350
  • 6
  • 14
  • the linked guide is the way to go, found the culprit (also nil coalescing operator) in a matter of minutes and was able to amend the code... – DonBaron Jan 01 '17 at 21:22
5

I had the same problem and solved it by painstakingly going through my code line by line, it turns out Swift 3 prefers string interpolation rather than using the + symbol, i.e.

let url = "http://yahoo.com" + "someWebPage" + "whereItsInteresting" 

If you have been using the above style of code replace it for;

let url = "http://yahoo.com\(someWebPage)\(whereItsInteresting)"

And your build time will immediately come back to normal.

silly_cone
  • 137
  • 1
  • 8
  • Same reason! the tool [https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode](https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode) helps me find out every bad files. – hstdt Apr 27 '17 at 13:39
4

for those who want to find where compiler is "caught"

Add to Other Swift Flags -Xfrontend -warn-long-function-bodies=50

check full answer here

Community
  • 1
  • 1
Constantin Saulenco
  • 2,353
  • 1
  • 22
  • 44
2

I tried the above solutions but the problem still happens. The debugging works weird, too. After some days research I found the solution below.

Select main target > Build Settings. Configuring as image below.

enter image description here

Tai Le Anh
  • 268
  • 3
  • 10
1

I encountered the same indexing issue, but it occurred only when I was running/debugging on a device and then switched to another device on the top-left toolbar (Target > iPhone).

None of the solutions above worked for me.

My solution: I removed my local git working copy and cloned a new one from my 'origin'.

(There are some 'magic' files within the xcuserdata/shared/session etc. folders that may have caused this issue?)

Tailz
  • 51
  • 1
  • 4
1

Not that I think this is related to OP's issue, but XCode 8 for me recently slowed to a halt. I eventually found it was my mistake (and I remember inadvertently doing it) - I added XCode.app as a Framework reference. This essentially made XCode search and index the entire XCode.app folder. Once I saw the mistake and remove the Framework it came good again :)

steve
  • 3,230
  • 1
  • 19
  • 14
1

I had a function that took over a minute to compile, and after some investigation, I found that the culprit was checking if enough time had elapsed from a stored date:

let myStoredDate: Double = // Double representing a time in the past

// if at least one week (60 * 60 * 24 * 7 seconds) has passed since myStoredDate
if Date().timeIntervalSince1970 - myStoredDate > (60 * 60 * 24 * 7){
    // do stuff
}

This code would take over 10 seconds to compile — coupled with this code being repeated with different numbers multiple times, it was causing compilation to take way too long. I was able to fix this by pre-computing the interval

let myStoredDate = // Double representing a time in the past

//it is important to explicitly specify that the variable is a Double
let interval: Double = 60 * 60 * 24 * 7

if Date().timeIntervalSince1970 - myStoredDate > interval{
    // do stuff
}

After doing this with the ~10 times I was checking, the compilation time was cut from over a minute to just a few milliseconds.

It's extremely likely that this problem also occurs with the combination of type-inferance and math elsewhere, so ensure that nothing like this happens anywhere else in your code.

Jojodmo
  • 23,357
  • 13
  • 65
  • 107
1

My problem was the dictionary. I had vary large dictionary.

let values = ["address":addressTextField.text,"city":cityTextField.text,"zipCode":zipCodeTextField.text,"state":stateTextField.text,"pet":answerLabel.text,"rentStart":rentStartTextField.text,"rentEnd":rentEndTextField.text,"rent":rentTextField.text,"phone":phoneTextField.text,"email":emailTextField.text,"status":leaseStatusTextField.text,"bedrooms":bedroomTextField.text,"parking":parkingLabel.text,"furnish":furnishLabel.text,"utilities":utilitiesTextField.text,"laundry":laundryTextField.text,"paymentCycle":paymentCycleTextField.text,"note":noteTextView.text]

I broke it down to:

        var values = ["address":addressTextField.text]
        values["city"] = cityTextField.text
        values["zipCode"] = zipCodeTextField.text
        values["state"] = stateTextField.text
        values["pet"] = answerLabel.text
        values["rentStart"] = rentStartTextField.text
        values["rentEnd"] = rentEndTextField.text
        values["rent"] = rentTextField.text
        values["phone"] = phoneTextField.text
        values["email"] = emailTextField.text
        values["status"] = leaseStatusTextField.text
        values["bedrooms"] = bedroomTextField.text
        values["parking"] = parkingLabel.text
        values["furnish"] = furnishLabel.text
        values["utilities"] = utilitiesTextField.text
        values["laundry"] = laundryTextField.text
        values["paymentCycle"] = paymentCycleTextField.text
        values["note"] = noteTextView.text
        values["owner"] = userID
Ahmadiah
  • 476
  • 5
  • 12
0

After add the setting,

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

our project clean-build compile times from 1200s to 180s for 650 swift files. But this will cause increase compile fail. Every change need 180s to compile when increase compile only need 60s

Suric
  • 131
  • 1
  • 4
0

It's a Xcode bug (Xcode 8.2.1) and it will happen when you have a large dictionary literal or a nested dictionary literal. You have to break your dictionary to smaller parts and add them with append method until Apple fixes the bug.

Saeed Ir
  • 1,974
  • 2
  • 20
  • 22
0

This works for me in Xcode 8.2.1 and Swift 3 when "Indexing" is stuck:

I always have two projects open, a dummy project and the project I'm working on. I also have a iPad Air device connected that I run my projects on. When my project gets stuck on "Indexing", I switch to my dummy project and run my project on my connected iPad Air device. Then I stop the project and switch back to the project I'm working on and the "Indexing" is magically finished. This should also work with the simulator only, if you don't have a physical device connected.

ironarrow
  • 53
  • 1
  • 9
0

Backup your project delete the last updated project after backingUp change the path of your project, and then restart Xcode simple and run the new upZip Backup:-)

Shakeel Ahmed
  • 5,361
  • 1
  • 43
  • 34
0

I've had similar problems and developed my own utility Rugby. In the current version, Rugby can cache all remote pods dependencies and remove their targets from the Pods project.\

Under the hood, it's using some optimizations. For example, like SWIFT_COMPILATION_MODE=wholemodule.

SwiftyFinch
  • 445
  • 2
  • 12
-1

What solves this for me is using keys to set dictionary values

let dict: [string:any]()
dict["key"] = "value"
dict["key1"] = "value"
dict["key2"] = "value"
return dict

If you have a long dictionary it may or may not cause a compile loop resulting in long build times. Anything longer than 8 keys should be set way.

user7684436
  • 697
  • 14
  • 39