Danny
Danny

Reputation: 4079

Xcode 8.0 Swift 3.0 slow indexing and building

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:

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?

Upvotes: 64

Views: 35396

Answers (17)

Shakeel Ahmed
Shakeel Ahmed

Reputation: 6013

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:-)

Upvotes: 0

SwiftyFinch
SwiftyFinch

Reputation: 475

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.

Upvotes: 0

Ahmadiah
Ahmadiah

Reputation: 476

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

Upvotes: 1

Jojodmo
Jojodmo

Reputation: 23596

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.

Upvotes: 1

steve
steve

Reputation: 3465

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 :)

Upvotes: 1

user7684436
user7684436

Reputation: 717

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.

Upvotes: -1

Tailz
Tailz

Reputation: 51

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?)

Upvotes: 1

ironarrow
ironarrow

Reputation: 53

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.

Upvotes: 0

silly_cone
silly_cone

Reputation: 157

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.

Upvotes: 5

Saeed Ir
Saeed Ir

Reputation: 2332

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.

Upvotes: 0

Constantin Saulenco
Constantin Saulenco

Reputation: 2383

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

Upvotes: 4

Suric
Suric

Reputation: 131

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

Upvotes: 0

Tai Le Anh
Tai Le Anh

Reputation: 278

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

Upvotes: 2

Stefan Nestorov
Stefan Nestorov

Reputation: 370

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.

Upvotes: 5

Ben Simon
Ben Simon

Reputation: 121

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"]

Upvotes: 6

Danny
Danny

Reputation: 4079

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)
    }
}

Upvotes: 23

Chris
Chris

Reputation: 40613

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

Upvotes: 54

Related Questions