Empty Class in Swift Playground Gives __lldb_expr_ Error - swift

Knocking up an empty class within a Swift Playground gives an error __lldb_expr_
//: Playground - noun: a place where people can play
import UIKit
class FooBar {
}
let foo = FooBar()
See attached screenshot.
This occurs on Xcode Version 6.3.1 (6D1002). I have also tried with the latest Xcode 6.4 beta 3 - Version 6.4 (6E7) - available 11th May 2015. The same error occurs.
Empty classes build without issue in a normal Swift project.
The error can be avoided by simply adding a dummy constant as follows:
//: Playground - noun: a place where people can play
import UIKit
class FooBar {
let wibble = 10
}
let foo = FooBar()
Was surprised at this error given that creating a initial empty class is such a basic thing. In my case I wanted a scroll view delegate class to track content offsets. It would seem entirely reasonable to use a delegate with no properties.
Any ideas?

This is not an error.
It's an information that the variable foo now holds an object of class FooBar whose internal name is __lldb_expr_12.FooBar. __lldb_expr_12 is the Swift module's name in the Playground in this case.

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.

Use of unresolved identifier: kCGWindowImageDefault (and other Core Graphics constants)

I'm new to Swift development. I'm writing an app for MacOS (not iOS) in Swift, and am trying to adapt some of the code from this Apple sample Objective-C project for use in my program.
The problem I'm hitting is that certain Apple-defined constants such as kCGWindowImageDefault and kCGWindowListOptionAll are causing XCode to report the compile-time error "Use of unresolved identifier [identifier]".
Somewhat surprisingly, though, if I right-click kCGWidowImageDefault and select "Jump to Definition", XCode does jump to the definition of that constant (in CoreGraphics > CGWindow.h > CGWindowImageOption) -- so XCode does seem to know what that constant is.
Here are the relevant snippets of my ViewController.swift file:
import Cocoa
import CoreGraphics
class ViewController: NSViewController {
...
func myFunction() {
// *** XCode reports the error on kCGWindowImageDefault on this line:
let imageOptions : CGWindowImageOption = kCGWindowImageDefault
...
}
}
The Apple documentation (as linked above) doesn't indicate what needs to be imported for these constants to be used.
XCode does appear to successfully recognize the types I'm using such as CGWindowImageOption -- it's just the constants that it isn't recognizing.
What do I need to do in order to successfully be able to use kCGWindowImageDefault and similar constants in my Swift MacOS program?
kCGWindowImageDefault is only for Objective-C, not Swift. In Swift, CGWindowImageOption is an OptionSet. For the default you simply use an empty option set:
let imageOptions : CGWindowImageOption = []
For CGWindowListOption you can do:
let listOptions: CGWindowListOption = .optionAll
Be sure you look at the Swift reference documentation for these enumerations. You can't use the Objective-C values.

Use of undeclared type 'AttributedString'

Xcode 8 beta 4 no longer recognizes Foundation class AttributedString.
I've reproduced it in this simple playground example:
//: Playground - noun: a place where people can play
import Foundation
let attrStr1 = NSAttributedString()
let attrStr2 = AttributedString() // Use of undeclared type 'AttributedString'
Since AttributedString was available in older Xcode 8 Swift 3 betas, I imagine this is a Foundation bug that needs to be fixed, rather than some source code error in Playground?
Although undocumented in the Xcode release notes, a version 2 update to Swift evolution proposal SE-0086 Drop NS Prefix in Swift Foundation has added the "NS" prefix back to several Foundation classes which previously dropped the prefix.
The reason is as follows:
If the class is planned to have a value-type equivalent in the near future, then keep the NS prefix. Examples: NSAttributedString, NSRegularExpression, NSPredicate.
So, the Swift AttributedString type will return at some point, as a struct next time, instead of being a class.
It sounds like some of these improvements will be "a focus area for Swift 4." For now, it's necessary to revert back to using the NSAttributedString class.
If you're curious to know how many types were affected by the SE-0086 v2 update, it looks like the revision affects ~32 types which had previously dropped the NS prefix for Swift 3.

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?

Why I can not change the value of global variable in WatchKit - swift?

I'm making a simple WatchKit application. I have a golbal int variable with value is 0 in first InterfaceController.
Here is my first interface:
import WatchKit
import Foundation
import UIKit
var index:Int = 0
class InterfaceController: WKInterfaceController {
.....
}
in the secondView Interface i want to change the value of this global variable:
import UIKit
import WatchKit
class secondInterfaceController: WKInterfaceController {
override init(context: AnyObject?) {
// Initialize variables here.
super.init(context: context)
// Configure interface objects here.
NSLog("%# init", self)
println("index: \(index)")
index = 2
}
}
But i received an error: "Cannot assign to the result of this expression" for variable index. I don't know why and i want to know how to do that. I can change the value of global variable for application for IOS. Thanks
I reproduced your code to test the problem, intending to test potential solutions. Instead, I confirmed that this issue was not reproducible.
To be able to run the code, I had to change it to override func awakeWithContext(context: AnyObject?). From the release notes of both beta3 and the beta4 released today:
The WKInterfaceController method initWithContext: has been deprecated. Please use awakeWithContext: instead. The designated initializer for WKInterfaceController is now init.
Given your code uses init(context: AnyObject?) and you are not receiving this error message:
Initializer does not override a designated initializer from its superclass
...it indicates that you are using a version of Xcode 6.2 earlier than beta 3. Therefore, it is possible there was a bug in an earlier beta that was causing your issue. Updating to today's beta4 release and re-testing this issue would be highly advisable.
On an associated note, there are many programmers who would argue that the use of global variables is highly undesirable, and that the use of another approach, even a singleton, is preferable. I just draw this to your attention to look into if you don't already have formed opinions on this debate.
I found a solution. When you want to use a global variable inside interfaces, you have to set all that interfaces to same "Target Membership"