Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a Swift type name as a string with its namespace (or framework name)

Tags:

ios

swift

Is there any way to get a Swift type name as a string with its namespace (or framework name)?

For example, if Foo.framework has a class named Bar, I would like to get a string something like "Foo.Bar".

The followings just return the class name "Bar".

let barName1 = String(Bar.self)       // returns "Bar"
let barName2 = "\(Bar.self)"          // returns "Bar"
let barName3 = "\(Bar().dynamicType)" // returns "Bar"

I would like to also get the framework name "Foo" as a namespace.

like image 252
Yoichi Tagaya Avatar asked Oct 31 '15 14:10

Yoichi Tagaya


People also ask

Is there namespace in Swift?

Swift currently doesn't offer a solution to namespace types and constants within modules. A common problem I run into when working with Swift is defining constants in such a way that they are easy to understand by anyone working on the project. In Objective-C, this would look something like this.

What is string describing Swift?

A string is a series of characters, such as "Swift" , that forms a collection. Strings in Swift are Unicode correct and locale insensitive, and are designed to be efficient. The String type bridges with the Objective-C class NSString and offers interoperability with C functions that works with strings.

What does .type do in Swift?

Type returns an instance of a metatype. There are two ways we can get an instance of a metatype: Call . self on a concrete type like Int.

Is string a class in Swift?

The String class in Swift provides various built-in functions that allow us to perform different operations on strings.


2 Answers

Use String(reflecting:):

struct Bar { }

let barName = String(reflecting: Bar.self) 
print(barName) // <Module>.Bar

From the Xcode 7 Release Notes:

Type names and enum cases now print and convert to String without qualification by default. debugPrint or String(reflecting:) can still be used to get fully qualified names.

like image 117
Martin R Avatar answered Oct 04 '22 02:10

Martin R


String(reflecting:) works right now, but could change in the future. So if you only need the fully-qualified name temporarily, you should be fine. However, if the name is something you're going to rely on over a longer period of time (spanning multiple releases of Swift) you shouldn't use it.

The Swift community is trying to come to a consensus on a longer-term method for getting the information from a type.

From Joe Groff:

In 4.2, String(reflecting:) still shows a fully qualified name for local types, but the local type context is anonymized and printed in a way that's intended to be clear is non-stable, since no matter what reflection support we add in the future, it'd be a bad idea to incidentally rely on the presence or identity of local types in dynamic code.

https://forums.swift.org/t/getting-the-more-fully-qualified-name-of-a-type/14375/9

like image 40
Clay Ellis Avatar answered Oct 04 '22 02:10

Clay Ellis