The swift compiler always 100% CPU - ios

I just added a Swift extension in my old Objective-C app. The Swift compiler is always at 100% CPU and hangs after I had run several times. I had tried restarting the Mac, but it's still the same.
I run Xcode6-Beta2 on OSX 10.9.3. Thanks.
Update:
I found these code cause this issue:
let defaults = NSUserDefaults.standardUserDefaults()
let lastURLBase: String? = defaults.objectForKey("HP-lastURLBase") as String?

I think the second line should be: let lastURLBase = defaults.stringForKey("HP-lastURLBase"). A constant (let) can't be optionally typed (?).

Related

NSCoding and Bools Swift 3

For whatever reason my application crashes everytime it decodes my Bool value. It didn't crash before I updated to Swift 3. I have no idea what I'm doing wrong. If I take out the Bool value my application runs fine without crashing.
This has been changed for Swift 3. There are associated decode...() functions for various different types.
The correct syntax is now:
let myBool = aDecoder.decodeBool(forKey: PropertyKey.completedKey)

Error after xcode 8 update - NSUserDefaults

After updating to Xcode 8.0 and iOS 10, I am getting an error in my code that I didn't before. Let me just walk you through the code that is bugging me.
viewDidLoad:
struct defaultsKeys {
static var localStrings = ""
}
Outside button (IBAction):
var storeUserData = NSUserDefaults.standardUserDefaults()
Inside button (IBAction):
let earlierStrings = storeUserData.stringForKey("localStrings")
The last one, inside the button, is the line that is giving me an error. I am now getting this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
And I wasn't before the update? Has something changed about NSUserDefaults? I am very confused and I hope you can help me :-)
First of all if you want to pass around values inside your program just use local variables as #vikingosegundo stated. Declare local variables and use them.
Second, use NSUserDefault when you want to store variables like for example user-settings or preferences. Do also follow #Adils advice. Use them as follows:
Set value:
NSUserDefaults.standardUserDefaults().setObject("YOUR STRING", forKey: "key")
Get value:
NSUserDefaults.standardUserDefaults().stringForKey("key")

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:
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?
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
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)
}
}
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"]
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.
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.
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
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.
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?)
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 :)
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.
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
Backup your project delete the last update project after backup and then restart Xcode simple :-)
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
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.
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.
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.
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.

Swift App Extension: instance method count is unavailable

I just create my first app extension using XCode 7.1. One code file containing the code below is shared with both targets:
var str = "";
var l = str.count; //Compile error for extension target App: count is unavailable: There is no ...
The reason for this compile error seams to be that App extension compiles with swift 1.2 while the container target compiles with swift 2.0.
One solution would be importing the content App into the extension App doesn't appear to be a good solution from what i read about it. Sharing the code between targets can be difficult if both are not compiled using the same compiler.
I just run through all target settings and didn't find nothing that could be changed.
Can't find any post about this problem, witch is not so uncommon, so it is must likely i am interpreting something in a wrong way.
The only solution i can think of is using NSString instead of String but that is just an workaround for one class type. More problems of this kind will emerge in the future.
In Swift 2 it's
str.characters.count
Use str.characters.count to get String length in Swift 2

EXC_BAD_ACCESS when updating Swift dictionary after using it for evaluate NSExpression

I'm using a dictionary to evaluate an expression, when the expression has variables and the dictionary is actually used by NSExpression, something happens and I get EXC_BAD_ACCESS when trying to update the dictionary, this only happens when debugging in an iPhone6, not in the simulator and not in an iPhone 4S.
let strExpression = "a+b+20"
let exp = NSExpression(format:strExpression)
self.dictionary = ["a":10.0, "b":15.0, "c":25.0]
let value:AnyObject = exp.expressionValueWithObject(self.dictionary, context: nil)
let doubleValue = value as Double
self.dictionary.updateValue(doubleValue, forKey: "c")
Something really weird is that if i add this line just after creating the dictionary, then it woks fine:
let newDic = self.dictionary
I,m using iOS 8.1. Thanks in advance!
With #bensarz comment, I thought it might be helpful for others searching for answers if I put the response into an actual answer instead of a comment.
Per #LeeWhitney's response on a similar post:
Looks like a compiler bug.
Have you tried switching between Release and Debug then rebuilding? If debug works but not release it can be an indication of a compiler/optimizer bug.
Does it happen in the simulator also?
Your code works for me on iOS 8.1 with XCode 6.1.
Solution:
The issue seems to be solved by changing the 'Optimization Level' under the 'Swift Compiler - Code Generation' to 'None'. The issue seems to be with the 'Fastest' Compiler optimization level.
Also, a work around that I've found original before the compiler change:
If you use a let statement prior to assigning values in the dictionary, it seems to alleviate the issue. More information found at link below:
EXC_BAD_ACCESS on iOS 8.1 with Dictionary

Resources