Swift ViewController class name as String [duplicate] - swift

This question already has answers here:
Get class name of object as string in Swift
(32 answers)
Closed 8 years ago.
I have a viewController called 'MyViewController' in which I want to save some values to the user defaults. As key I wanted to use the class name "MyViewController" and append some string. Is it possible in Swift to get the String out of a class name? Thanks for any help :)

There may be a better way to do this, but as far as I know, you can get at the class name via classForCoder() (NSObject subclasses only). From there, you can use NSStringFromClass to convert the class name to an NSString. Only problem is the the name will often come out mangled, maybe "__lldb_expr_690.MyViewController". You can get around this by explicitly setting the name, ex:
#objc(MyViewController) class MyViewController: UIViewController {
func aMethod() {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some Object", forKey: NSStringFromClass(self.classForCoder))
defaults.synchronize()
// Has set "Some Object" for key "MyViewController"
}
}

class MyOwnClass {
}
var myVar1 = NSString()
var myVar2 = MyOwnClass()
println(_stdlib_getTypeName(myVar1)) // Gives "NSString"
println(_stdlib_getTypeName(myVar2)) // Gives "_TtC15__lldb_expr_26410MyOwnClass"

Related

what does constant property means in swift? [duplicate]

This question already has answers here:
What is the difference between `let` and `var` in Swift?
(32 answers)
Closed 5 years ago.
I am learning SWIFT. I don't understand one sentence while reading book. What does the sentence below means?:
“Add a constant property called elementList to ViewController.swift
and initialize it with the following element names: let elementList =
["Carbon", "Gold", "Chlorine", "Sodium"]”
does it mean create new class or I have to create struct?
In you situation, you are creating an array of string and store it into a constant variable called elementList. When you use let to create this variable, it means that the value cannot be changed afterwords. So you cannot add or remove element after declaring this array in this way, etc
class ViewController: UIViewController {
var intValue = 1 //This is a property, but it is variable. That means its value can be changed in future.
let doubleValue = 3.14 // This is a property too, but it is constant. That means its value can't be change
// Both `intValue` & `doubleValue` will be in memory till ViewController's existence.
}
IN YOUR CASE:
let elementList = ["Carbon", "Gold", "Chlorine", "Sodium"]
elementList is a array of String, since let keyword denotes that it is a constant property
To Add a constant property called elementList to ViewController.swift and initialize it. IT WOULD LOOK SOMETHING LIKE THIS
class ViewController: UIViewController {
let elementList = ["Carbon", "Gold", "Chlorine", "Sodium"]
//..
}

NSMapTable "Generic parameter 'KeyType' could not be inferred" [duplicate]

This question already has an answer here:
Declare "NSMapTable StrongObject" in Swift 3
(1 answer)
Closed 6 years ago.
The following line is giving me the compiler error "generic parameter 'KeyType' could not be inferred":
fileprivate var delegatesMap = NSMapTable.strongToWeakObjects()
I tried being more explicit by saying:
fileprivate var delegatesMap:MapTable<Key,Value> = NSMapTable.strongToWeakObjects()
But I then Xcode doesn't recognize "Key"
How do I go about fixing this?
EDIT: I would like my Key to be of type String, and my Value to be of type MenuActionDelegate(class protocol)
You may need to write something like this:
fileprivate var delegatesMap = NSMapTable<NSString, MenuActionDelegate>.strongToWeakObjects()
The generic parameters KeyType and ValueType need to be AnyObject, so you cannot directly put String there, also you need some explicit casting as NSString.
And the value type MenuActionDelegate needs to an #objc-protocol.
Or else you may need to write something like this:
var delegatesMap = NSMapTable<NSString, AnyObject>.strongToWeakObjects()
And use it as:
let theDelegate = delegatesMap.object(forKey: "delegateName" as NSString) as! MenuActionDelegate

Swift: get the compile time name of variable (referencing to a class)

Is there a way to get the compile time name of a variable in Swift 2?
I mean the first variable name, which references to a new class instance, if any.
Here is a simple example:
public class Parameter : FloatLiteralConvertible {
var name:String?
var value:Double
// init from float literal
public required init (floatLiteral value: FloatLiteralType) {
self.value = Double(value)
self.name = getLiteralName()
}
func getLiteralName () -> String {
var literalName:String = ""
// do some magic to return the name
return literalName
}
}
let x:Parameter = 2.0
print(x.value) // this returns "2.0"
print(x.name!) // I want this to return "x"
I've already checked similar questions on that topic handling mirroring or objective-c reflections. But in all those cases, one can get only the property names in a class - in the example above name and value.
The same question has been asked in 2014 - Swift: Get Variable Actual Name as String
- and I hope, that since then there is a solution in swift 2.
No, there is no way to do that.
You have to understand that in the compiled state that variable usually does not exist. It can be optimized out or it is represented only as an item on the execution stack.
Even in languages with much better reflection that Swift has, usually you cannot inspect local variables.
To be honest, getting the name of a local variable dynamically has no practical use case.

How to Initialize a class from a string in Swift [duplicate]

The following code prints nil, despite ListCell is a valid class.
var lCellClass : AnyClass! = NSClassFromString("ListCell");
println(lCellClass);
The docs are saying that method returns
The class object named by aClassName, or nil if no class by that name is currently loaded. If aClassName is nil, returns nil.
I also tried to get NSClassFromString() of current viewcontroller which is LOADED but still get nil
What can be the problem ?
Update:
Even trying to do this NSClassFromString("Array") I still get nil
The NSClassFromString function does work for (pure and Objective-C-derived) swift classes, but only if you use the fully qualified name.
For example, in a module called MyApp with a pure swift class called Person:
let personClass: AnyClass? = NSClassFromString("MyApp.Person")
The module name is defined by the "Product Module Name" (PRODUCT_MODULE_NAME) build setting, typically the same name as your target (with some normalization applied to e.g. remove spaces).
This is atypical, but if the class you're loading is in the current module and you don't know the module name at compile-time e.g. because the code is compiled as part of multiple targets, you can look up the bundle name dynamically, which usually corresponds to the module name:
let moduleName = Bundle.main.infoDictionary!["CFBundleName"] as! String
let personClass: AnyClass? = NSClassFromString(moduleName + "." + "Person")
I don't recommend this however unless you really don't know at compile-time.
See Using Swift Class Names with Objective-C APIs in Using Swift With Cocoa and Objective-C for more information.
It's also possible to specify a name for the symbol in Objective-C which omits the namespace in objective C by using the #objc annotation. If you prefer to use the name without the module, just use the same class name:
#objc(Foobar)
class Foobar{
}
NSClassFromString("Foobar") will return the class Foobar.
This may be problem that your class have not extend from NSObject. As by default swift does not have superclass.
For example:
Just using UIViewController as an example,
func getVc(from stringName: String) -> UIViewController? {
let appName = Bundle.main.infoDictionary!["CFBundleName"] as! String
guard let vc = NSClassFromString(appName + "." + stringName) as? UIViewController.Type else {
return nil
}
return vc.init()
}
If your App name contains "-" or number, just replace them with "_"

How do you retrieve the type of an object in Swift? [duplicate]

This question already has answers here:
How do I print the type or class of a variable in Swift?
(34 answers)
Closed 8 years ago.
I cannot seem to find a function or method that returns the type of an object in Swift.
How does one retrieve the type or class of an object in Swift?
I tried using Obj-C classes which obviously did not work.
In python you have things like type or isinstance
In Javascript you have constructor
If you just need to check an object's type, you can use the type check operator, is, as in:
if myObject is UIView {
// do something
}
If you want to try to call a method on the object but you aren't sure of the class, downcast the object to the type you need, like this:
if let myView = myObject as? UIView {
myView.layer.backgroundColor = myColor
}
Are you looking for dynamicType?
someInstance.dynamicType.printClassName()