Segmentation fault in Swift compiler when converting to Swift 4 syntax - swift

I have some Swift code that was written in Swift 3.2, and I just attempted to use the automatic syntax converter in Xcode 9.0 to update to Swift 4.0.
It actually found nothing that needed to be converted, but during the code analysis when the compiler compiles the project, the compiler crashes with a segmentation fault. I can't share the full source code, so I created a simple example which demonstrates the same issue, and confirmed that this also produces a crash in a newly-created Swift project.
The compiler crash only appears when joining values together using string interpolation. To reproduce:
Create a new Xcode project, and set Swift version to 3.2
Create a new Swift class
Paste the following code into the new class:
public class SomeClass: NSObject {
static let defaultStringPrefix = "abc"
var a: String = ""
var b: String = ""
var c: String = ""
lazy var concatStr: String = {
let str = "\(defaultStringPrefix)/\(self.a)/\(self.b)/\(self.c)/somepage.html"
return str
}()
}
Attempt to perform the Swift 3.2 to Swift 4.0 conversion -> This will fail and a segfault will appear with the following error:
Command failed due to Segmentation fault: 11
Stack dump:
0....(a huge load of arguments to the swift compiler)
1. While type-checking getter for concatStr at /Users/craigrouse/mobiledev/test/test/SomeClass.swift:17:14
2. While type-checking declaration 0x7ff292a86400 in module 'test'
3. While type-checking expression at [/Users/craigrouse/mobiledev/test/test/SomeClass.swift:17:34 - line:20:7] RangeText="{
let str = "\(a)/\(b)/\(c)/somepage.html"
return str
}()"
I've tried various versions of this, and if I remove the string interpolation, the problem goes away. Obviously I could avoid using the auto conversion, and set the Swift version to 4 manually in the project settings, but I'm sure others will encounter this mysterious error, and I'd like to find out what's causing it. Is there a problem with my syntax?
Thanks.

Related

Cannot access enum case's rawvalue defined in a global constants file

I have a global constants file: Constants.swift in an iOS app project. Xcode version is 11.1.
The code in this file:
import Foundation
struct Constants {
enum DayOfTheWeekend : Int {
case Saturday = 1
case Sunday = 2
}
}
In a different file in the same iOS app project, I have this code in a func within a class:
let day = Constants.DayOfTheWeekend.Saturday.rawvalue
And I get this error:
Value of type 'Constants.DayOfTheWeekend' has no member 'rawvalue'
If I put enum outside of the struct in the same Constants.swift file, I still get the same error.
When I type "Constants.DayOfTheWeekend.Saturday.", Xcode autocomplete feature suggests only "self" and "hashvalue". There is not any rawvalue option.
Where is my mistake?
The syntax is rawValue. See The Swift Programming Language: Enumerations: Raw Values.
Why do you think Xcode autocomplete doesn't suggest that?
It does:
But sometimes autocomplete gets confused, especially if there are some errors elsewhere in one’s code. It also won’t work if the file with the enumeration hasn’t been saved. And sometimes it just gets sufficiently confused that you have to empty the derived data folder and restart Xcode.

Xcode 7.3 undeclared type for Obj C enum in Swift code

In my project I have Swift extensions over Objective C enums, which worked brilliantly in Xcode 7.2.
But with Xcode 7.3 it fails with "undeclared type" in the Swift file where I extend the Obj C enum.
I've built a sample project and it compiles and works well, but I can't make the existing project accept the extension over the Obj C enum.
UPDATE:
After reinstalling Xcode 7.2 I can confirm that the project compiles and builds successfully.
After it worked in Xcode 7.2, I tried launching this project again in Xcode 7.3 and again the same issue -> the Swift extension over Obj C enums can't be build.
After cleaning and deleting the derived data in Xcode 7.3 I receive also the -Swift.h header missing error because the Swift classes haven't been compiled so a header wasn't created yet.
Code explanation:
My Obj C enum inside "FriendRequestResult.h":
typedef NS_ENUM(NSInteger, FriendStatus)
{
FriendStatusRequestedByUser = 1,
FriendStatusRequestedByOtherUser,
FriendStatusFriends,
FriendStatusBlocked,
FriendStatusNone,
FriendStatusError,
};
Now, as expected in my AppName-Bridging-Header.h I have:
#import "FriendRequestResult.h"
Then, I have the swift extension over the FriendStatus which builds in Xcode 7.2, but fails with "use of undeclared type" in Xcode 7.3:
extension FriendStatus
{
init(stringValue : String?)
{
if let stringValue = stringValue
{
switch stringValue
{
case "REQUESTED_BY_USER": self = .RequestedByUser
case "REQUESTED_BY_OTHER": self = .RequestedByOtherUser
case "FRIENDS": self = .Friends
case "BLOCKED": self = .Blocked
default: self = .None
}
}
else
{
self = .None
}
}
}
Actually this extension over the enum has also some other helper functions, but that should not change the problem in any way.
Of course if the extension of the enum gives the undeclared type, then using this type fails everywhere in the Swift code with the same "undeclared things". Basically the enum is not visible at all for the Swift part of the project, even though the import is made in the bridging header.
This question was substantially edited from its first version.
Solution 1:
Moved the enum in a seaparate header file.
My enum declaration was in the same header as a class header and specifically it was between the #interface and #end of that class.
In Xcode 7.2 it was creating no issues and the parsing of the header was successful, while in Xcode 7.3 they probably optimised something and changed the way it's parsed, so it was seeing my class, but not the enum inside it [maybe it declares it as private if it's inside a class declaration]
Solution 2: Moved the enum declaration outside the #interface #end scope.
To answer your question: "Can I somehow force Xcode to generate the Swift header first? Or can I force Xcode to believe that my enums exist somewhere and that it should validate my extensions?"
I found 2 ways to order file compilation.
Using a target and making it a dependency of your project.
Opening the project.pbxproj file and editing the list manually.
Depending on the level of risk and complexity you are ready to tackle, pick one or the other.
I just tried extending an ENUM and things are working fine here. One issue I had in the past was understanding the name stripping convention between Obj-C and Swift but this doesn't look like the issue you are running into.
The other issue I encounter invariably is maintaining the ##$% Bridging-Header.h file all the time. Are you positive this is up-to-date?

Cannot invoke "Int" with an argument of type "String"

When I use this code from apple book in my playground:
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
Xcode shows an error:
Cannot invoke "Int" with an argument of type "String"
But compiler should refer convertedNumber as optional, as I understand.
You must be using Swift 1.x (in Xcode 6), but the Swift book is for the last version of Swift, currently 2.1 (in Xcode 7). The String initializer for Int() wasn't available in Swift 1.
I was able to make this work with no issues. It could be the XCode causing the issue. Try a reinstallation of the XCode.

Objective-C Runtime API in swift

I try to use the old Objective-C runtime APIs in swift. But I can't get the correct result:
import Foundation
class MyClass
{
let a : UInt32 = 10
func test(){ }
}
var obj = MyClass()
println("%#",class_getSuperclass(MyClass)) //ExistentialMetatype
println("%#",objc_getClass(UnsafePointer<Int8>(unsafeAddressOf(obj)))) //nil
The result of first println is "ExistentialMetatype". The second println gives nil. My Questions are:
What is the type of "ExistentialMetatype"?
I also tried other runtime APIs but they all failed. So far, I can't find any Apple docs related to this topic. And It seems like the only way to get the meta-class(isa pointer) information is through reverse engineering.
Does this mean Swift prevents us from accessing the meta-class at runtime?
The above code is running on XCode 6.1.1

xcode 6 beta 4 new Swift issues with NS_ENUM defined in Objective C

Just started to use Xcode6 beta 4 and have come up against an issue that was not there before. I define my NS_ENUM in my objective-c as follows:
typedef NS_ENUM( NSInteger, ToolbarType ) {
tb_closed_k = 0,
tb_text_k = 10,
tb_shape_k,
tb_undefined_k
};
Then in my swift code i want to set a variable to one of these values:
var test = ToolbarType. tb_undefined_k
This was working without issues in beta 3 but now I get an error that :
'ToolbarType' does not have a member named 'var test = ToolbarType. tb_undefined_k'
After investigating further, if I type the enum type followed by a ., auto completion shows me the options and it suggests the value to be:
ToolbarType.b_undefined_k
is seems very odd. Is this a bug or some kind of naming convention? I am afraid if I use these suggested values, in the next release they all become broken.
Any suggestions. Thanks.
Reza
After playing around I found that if I added a value to the end of the enum that did not in anyway conform to the naming convention of the values that proceeded it then the error would go away. In fact I just added "dummy" to the end my list of enums and it all started to work