19

I'm trying to print the name of the current class in Swift. More specifically, I'd like achieve the following output:

myFunction() in ClassContainingTheFunction

I have the function name printing fine. This is the closest I've came to printing the class name along with the function name:

println("\(__FUNCTION__) in \(__FILE__)") 

prints

myFunction() in path/to/TheFile.swift

and

 println("\(__FUNCTION__) in \(object_getClassName(self))")

prints

 myFunction() in [mangled class name here]

Both of these are close to what I want, but the path is long, and the mangled class name can be very unreadable compared to the name I see in code.

Ben Kane
  • 9,331
  • 6
  • 36
  • 58
  • possible duplicate of [How do you find out the type of an object (in Swift)?](http://stackoverflow.com/questions/24101450/how-do-you-find-out-the-type-of-an-object-in-swift) – Lou Franco Jun 30 '14 at 16:49
  • or this: http://stackoverflow.com/questions/24006165/how-do-i-print-the-type-or-class-of-a-variable-in-swift – Lou Franco Jun 30 '14 at 16:52
  • 2
    @LouFranco For the first link: I'm not trying to find out the type. I'm trying to print the name of the class the `println()` call is in. For the second link: That question has an accepted answer and it is not what I'm looking for. I'm also not worried about finding the class of any object, I want to know the current class' name. – Ben Kane Jun 30 '14 at 16:55

6 Answers6

28

So your problem is only the long path for the shown String. My best idea would be to shorten the String to the filename only.

var test: String = "/Users/user/Project/classfile.m"

test = test.lastPathComponent // here it is only classfile.m
test = test.stringByDeletingPathExtension // here it is only classfile

Since object_getClassNAme(...) will use the real used class and not the name you used like the the class cluster, it is the wrong way for you. Learning the concrete class implementation names would make it easier though.


Instead of test you use your way of getting the filename, like __FILE__. The following code produces the output you are looking for:

println("\(__FUNCTION__) in \(__FILE__.lastPathComponent.stringByDeletingPathExtension)") 

Swift 2.2

In Swift 2.2 those old identifiers are deprecated and replaced with #file, #line, #column, and #function.

print("\(#function) in \(#file.components(separatedBy: "/").last ?? "")")

Output example:

file81.swift
Community
  • 1
  • 1
Binarian
  • 12,296
  • 8
  • 53
  • 84
  • This does not answer the question he is looking for a [[self class] description] equivalent. – kubbing Aug 20 '15 at 08:11
  • @kubbing Should have answered you back in August when you commented, sorry. To be clear, this does actually answer what I wanted. What you proposed would print the name of the object, I wanted the name of the file the func is called in. Not necessarily the same thing. – Ben Kane Feb 02 '16 at 19:21
  • 3
    In Swift 2.2, use #function and #file instead of \_\_FUNCTION\_\_ and \_\_FILE\_\_. – user2067021 Apr 12 '16 at 01:45
3

I wanted a solution that logged out a nice neat string like this (Swift 3.0) - Class Name - Function Name. eg :

OnboardingGetStartedController - viewDidLoad()

So I ended up with a short function that Ive put in my utils class, like this :

class func logCurrentFunc(fileStr: String, funcStr: String) {

    var fileName = fileStr.components(separatedBy: "/").last ?? ""
    fileName = fileName.components(separatedBy:".").first ?? ""
    let printFunc = "\(fileName) - \(funcStr)"
    print(printFunc)
}

And I call this from anywhere in the app, like this :

Utils.logCurrentFunc(#file, funcStr: #function)

Its just a bit neater looking than other suggestions.

Luke Smith
  • 1,218
  • 12
  • 17
2

My short answer is,

print(" Function name : \(#function), Class Name : \(self.dynamicType), File Path : \(#file)")
2

In swift 3 it is now #file and #function

Hope that helps.

Jamil
  • 1,825
  • 1
  • 11
  • 11
1
print("=== \(type(of: self)).\(#function):\(#line) - message")

result

=== HomeScene.onAppear():189 - message
Hun
  • 3,652
  • 35
  • 72
0

I think the following is what you want (in Swift 2.1 and up):

print("\(__FUNCTION__) in \(self.dynamicType)")
Mark A. Durham
  • 844
  • 1
  • 6
  • 18
  • Hi Mark. That's not quite the same thing. That's the name of the object. I wanted the name of the file the func is being called in. The accepted answer as is still needs some updating because you have to cast to NSString now and println is print, but it's still correct. Thanks for the input. – Ben Kane Feb 02 '16 at 19:19