18

I have a static method in Swift

class BaseAsyncTask: WebServiceClient {
      class func execute(content : [String:AnyObject], cancelled:CustomBool)
      {
            // Print class name (BaseAsyncTask) here
      }
}

And I want to know how to get the class name inside that method. I tried

self.dynamicType

but that gives error (I suppose because of the self inside a class function)

Oscar Vasquez
  • 465
  • 2
  • 6
  • 14

3 Answers3

13

There are different methods to do that, if your method inherits from NSObject you can expose it to objective-c and do something like that.

@objc(BaseAsyncTask)

class BaseAsyncTask: WebServiceClient {
      class func execute(content : [String:AnyObject], cancelled:CustomBool)
      {
            println("Class \(NSStringFromClass(self))")
      }
}

For pure SWIFT introspection check here about MirrorType

I've found also this extension credits to ImpactZero

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

    public var nameOfClass: String{
        return NSStringFromClass(type(of: self)).components(separatedBy: ".").last!
    }
}

[Xcode 8]
Alex suggested me that in the Xcode 8 version this code shows a warning. To avoid that we should prefix the method like that:

@nonobjc class var className: String{ 
   return NSStringFromClass(self).components(separatedBy: ".").last!
}
Community
  • 1
  • 1
Andrea
  • 26,120
  • 10
  • 85
  • 131
  • NSStringFromClass(self).componentsSeparatedByString(".").last! worked as a charm. Didn't occur to me to try self without dynamicType, thanks. – Oscar Vasquez Aug 04 '15 at 14:47
  • @Andrea, I would also suggest to add `@nonobjc` attribute before `public class var nameOfClass` to avoid the following warning (Xcode 8.2): "ld: warning: Some object files have incompatible Objective-C category definitions. Some category metadata may be lost. All files containing Objective-C categories should be built using the same compiler." Like so: `@nonobjc class var className: String{ return NSStringFromClass(self).components(separatedBy: ".").last! }` – Alex Feb 16 '17 at 18:40
10

You can use string interpolation to print self:

let className = "\(self)"

Sample code:

class BaseAsyncTask: WebServiceClient {
    class func execute(content : [String:AnyObject], cancelled: CustomBool)
    {
        let className = "\(self)"
        print(className)
    }
}

class AnotherAsyncTask : BaseAsyncTask {
}

BaseAsyncTask.execute([:], cancelled: true) // prints "BaseAsyncTask"
AnotherAsyncTask.execute([:], cancelled: true) // prints "AnotherAsyncTask"
Antonio
  • 71,651
  • 11
  • 148
  • 165
7

Another way to do this, when you don't have an instance of the class is this.

Swift 4

print(String(describing:BaseAsyncTask.self))

Swift 2

print(String(BaseAsyncTask))

Inspired here.

Get class name of object as string in Swift

Bruno Coelho
  • 926
  • 13
  • 25
  • 1
    This doesn't work in Swift 4. You need to use something like: `String(describing:BaseAsyncTask.self)` – ThomasW Feb 15 '18 at 07:42