web-dev-qa-db-fra.com

Obtenez une version lisible par l'utilisateur du nom de la classe dans Swift (dans l'objet, NSStringFromClass était parfait)

Existe-t-il un équivalent de NSStringFromClass dans Swift qui donne une version lisible par l'utilisateur du nom de la classe? J'ai essayé de l'utiliser avec une classe Swift native que j'ai créée, mais comme vous pouvez le constater, le résultat semble être la représentation interne du nom de la classe par le compilateur:

println(NSStringFromClass(MyClass.self))

Résultat:

_TtC5test7MyClass

J'ai essayé d'ajouter l'attribut @objc à la classe et d'en faire une sous-classe de NSObject, mais cela ne fait aucune différence. J'ai découvert que si je remplace MyClass par une classe Objective-C du même nom et l'importe dans l'en-tête de pontage, cela me donne «MyClass», mais cela ne devrait pas être nécessaire.

Une autre option serait de créer un protocole pour cela, auquel chaque classe que je veux utiliser de cette manière doit se conformer:

protocol Nameable {
    class var className: String { get }
}

Cependant, il serait plus facile d’avoir un moyen intégré de le faire dans la langue.

29
jfla

Vous pouvez maintenant faire: 

String(MyClass)
61
NatashaTheRobot

nouveau format basé sur xcode 6 beta 5.

(nom_projet). (nom_classe)

func getName(classType:AnyClass) -> String {

    let classString = NSStringFromClass(classType.self)
    let range = classString.rangeOfString(".", options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)
    return classString.substringFromIndex(range!.endIndex)
}

Dernières 6.3 Xcode Swift 1.2

si vous avez besoin d'une extension ou que vous pouvez la placer sur n'importe quel objet commun

public extension NSObject{
    public class var nameOfClass: String{
        return NSStringFromClass(self).componentsSeparatedByString(".").last!
    }

    public var nameOfClass: String{
        return NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
    }
}
25
ImpactZero

Swift 3

type(of: self)prints NomModule.NomClasse

String(describing: type(of: self))prints ClassName

13
Timonea

Dans Swift 2 beta 4, vous pouvez accéder aux informations via l’objet type:

let className = "\(String.self)"   // gives: "Swift.String"

ou si vous avez une instance:

let s = "Hello World"
let className = "\(s.dynamicType)" // gives: "Swift.String"

Vous obtenez le résultat Module.Class, comme:

Swift.String
ABC.MyGenericClass<Swift.Int>

Assez drôle, l'objet Type renvoyé ne semble pas être conforme au protocole CustomStringConvertible. Par conséquent, il n'a pas de propriété 'description', bien que le motif "" fasse toujours ce qu'il faut.

P.S .: Avant b4, on pourrait accomplir la même chose avec reflect (obj.dynamicType) .summary.

5
hnh

Pour le moment, il n’existe aucun moyen fiable de le faire. Voir le commentaire d'un développeur Apple sur https://devforums.Apple.com/thread/227425

Swift n’a actuellement pas beaucoup d’introspection. 

Il existe des machines d’introspection qui sont utilisées pour le cours de récréation. Je ne sais pas si c'est destiné à être une API.

Certains Swift les méthodes et les variables peuvent être examinées à l'aide du fichier runtime d'Objective-C introspection. C'est probablement la meilleure solution aujourd'hui.

Swift a la notion de métatype, un peu analogue au type de classe dans Objective C. Vous pouvez le trouver avec TypeName.self, par exemple

class Foo {
    @required  init() {
    }
}

var normalFoo : Foo = Foo()
var fooType : Foo.Type = Foo.self;
var fooFromMetatype : Foo = fooType();

Peut-être qu'à la fin de la publication, les métatypes incluront davantage de capacités d'introspection. Je suggère de déposer une demande de fonctionnalité radar pour cela.

5
Adam Wright

Dans Swift v3.0, cela fonctionnait pour moi:

String.init(describing: self.self)
3
Coach Roebuck

----- Mis à jour -----

Comme @ThomasW l'a mentionné, pour Swift 4, nous devons utiliser String(describing:type(of:self))

----- Ancien poste ----

Je préfère utiliser String(self.dynamicType)

Utilisez-le dans mon projet https://github.com/JakeLin/SwiftWeather/blob/e7165b0919dda53fd7fcba9b43fdfe150d73c6f8/SwiftWeather/ForecastView.Swift#L135

2
Jake Lin

C'est un peu plus court. Pas besoin de NSStringFromClass

MyObject.self.description().componentsSeparatedByString(".").last!
1
nacho4d

Voici Swift 3+, Xcode 8+ exemple avec le code:

class MySuperbClass{
    let a = 4
    func getClassName() -> String? {
        return String(describing: type(of:self)).components(separatedBy: ".").first
    }
}


let className = String(describing: type(of:MySuperbClass.self)).components(separatedBy: ".").first
//className = "MySuperbClass" 
let classNameFromObject = MySuperbClass().getClassName()
//classNameFromObject = "MySuperbClass"
1

Si vous voulez avoir uniquement le nom de la classe dans Swift, vous pouvez analyser la chaîne renvoyée par NSStringFromClass ().

Ceci est fait dans nameOfClass.Swift du référentiel INSwift Github: https://github.com/indieSoftware/INSwift

1
Sven

Vous ne devriez pas pouvoir utiliser ce qui suit pour récupérer le nom de la classe dans Swift

let nameSpaceClassName = NSStringFromClass(RWTCountryPopoverViewController.self)
let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String
1
TheCodingArt

Swift 3

NSStringFromClass(self).components(separatedBy: ".").last!
0
anoop4real
myObject.description().componentsSeparatedByString(" ").first!

Ce n'est pas exactement ce que vous voulez - cela ajoutera un '<' et un ':' 'suivants: Mais lorsque je débogue, je privilégie la vitesse à la propreté pour que cette astuce rapide + sale fonctionne pour moi.

0
Rolf Hendriks

Swift 4 

super.init(nibName:String(describing:MyClass.self), bundle: nil)
0
DMagaro