How to Create an Instance of a Class from a String in Swift

How to create an instance of a class from a String in Swift

You can try this:

func classFromString(_ className: String) -> AnyClass! {

/// get namespace
let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String

/// get 'anyClass' with classname and namespace
let cls: AnyClass = NSClassFromString("\(namespace).\(className)")!

// return AnyClass!
return cls
}

use the func like this:

class customClass: UITableView {}   

let myclass = classFromString("customClass") as! UITableView.Type
let instance = myclass.init()

How to find a class instance name in other class in swift?

You can get variable name only in this way

class MyClass {
func printInstanceNameIn(user: User) {
let mirror = Mirror(reflecting: user)
for (label, value) in mirror.children {
if let value = value as? MyClass, value === self {
print(label!)
}
}
}
}

class User {
var firstObject: MyClass!
var secondObject: MyClass!
}

let u = User()
u.firstObject = MyClass()
u.secondObject = MyClass()
u.firstObject.printInstanceNameIn(user: u)

How do I access an instance of a class in Swift

You should keep a reference to the User object in a singleton in order to access it every where. Basically in cases like this you have a singleton class called say CurrentUser

class CurrentUser {
static var sharedInstance = CurrentUser()
var user:User?
}

Then in your network call or perhaps in the completion handler of the first view controller you where you know the first time the user is obtained you can set the User instance to the CurrentUser singleton.

CurrentUser.sharedInstance.user = myUser

Later you can use CurrentUser.sharedInstance.user in all the places where you want to get the user details.

How do I create an instance of a class from the child of a Mirror object in Swift

Your code won't work but the error you get is wrong so you should ignore it.

The real problem is you can't just blindly call init() on the type of an Any. There are a lot of types that don't have an init() at all. It works on type(of: s) in your first example because the compiler knows at compile-time that the type is String (and that String has an init()). But if you wrap it in Any then it fails as well:

let s = String("Foo") as Any
let typeClone = type(of: s).init()

Unfortunately this means there's no way to do what you're trying to do.

Creating a new instance of a class with a protocol-conforming class as an argument

You don't need to pass any type at all. The using parameter is completely unnecessary. Delete it. This is a generic; passing the type makes the generic pointless!

Just resolve the generic when you declare what you want to instantiate. (And do not call something Data, that name is taken.)

So, if we start with this:

protocol DataFetcherType {
init(_ mainData: String, fetchData: Bool)
}
class DataFetcher1: DataFetcherType {
required init(_ mainData: String, fetchData: Bool) {
}
}
class DataFetcher2: DataFetcherType {
required init(_ mainData: String, fetchData: Bool) {
}
}

... then this is all you need:

struct MyData<FetcherType: DataFetcherType> {
var mainData: String
var fetcher: FetcherType
init(_ mainData: String, fetchData: Bool = true) {
self.mainData = mainData
self.fetcher = FetcherType.init(mainData, fetchData: fetchData)
}
}

...because to make one, you can just resolve the type:

    let mydata = MyData<DataFetcher1>("hey")

Also, notice that I have changed the type of the variable fetcher. It should be the generic type, not the protocol.

In general if you find yourself passing types around in Swift, that's a bad smell and you should rethink. It can be done, and it sometimes is done, but on the whole Swift does not like metatypes and you should avoid them.

And the same is true of protocols; if you find you are typing something as a protocol, rethink.

This is exactly why generics exist, so you don't do those things.



Related Topics



Leave a reply



Submit