1

I'm currently working on introspection in Swift 2 and have Problems getting the specific type for an Array (in this example an Array<String>).

var prop = obj.valueForKey("strings")!

if prop is Array<String> {
println("true")
}
if prop is Array<Int> {
println("true")
}

Output is:

true
true

while it should be

true
false

Is there a way to find out the type for the members of the Array? For example, if I daclared the Array as Array<String> I want to get String or at least be able to check if it is. MirrorType also did not lead to any success on that by now.

2
  • Btw. prop is String gives false as expected. Commented Oct 14, 2015 at 8:01
  • If this helps, reflect(prop).valueType gives Swift.Array<Swift.AnyObject>. Commented Oct 14, 2015 at 8:20

2 Answers 2

1

There are 2 ways to achieve what you want:

  1. if prop.dynamicType == Array<Int>.self (or [Int].self) which is better than if prop.dynamicType == [Int]().dynamicType { because [Int]() creates an unused instance of "array of integers".
  2. Typically, when you check if an array is specific-typed, you plan to use it in a certain way (as a result, you will likely cast your array to [Int]). Having that said, I recommend using if let arrayOfInts = prop as? Array<Int> {. Using this construct, you will check for type compatibility and prepare your array to be treated in a special way (using the casted arrayOfInts reference).

Anyway, it's up to you to decide what to do.

Sign up to request clarification or add additional context in comments.

3 Comments

This won't work too as Swift recognizes an empty Array as Array<AnyObject> no matter how you instantiate it. Therefor the check always returns true.
I've tried that in a Swift 2.0 playground and it work exactly as I described. Maybe I fails for Swift 1.x. Cheers.
Turned out the environment I was testing on had Swift 1 on it.
1

Perhaps what you want is the type of each individual item inside the Array rather than the type of the Array itself? If you are using collection types in Swift, all the items stored in the Array (or Dictionary) are of the same type (except if you declare the Array as Array for example to break the rules... which is not usually necessary, or wanted).

By declaring an Array with its initially values you are automatically telling the compiler what type they are. If you do something like this:

let obj = [1,2,3]
var property = obj[0]

if property is String {
    print("true")
}
if property is Int {
    print("true")
}

The compiler will already tell you that property is String always fails, and there is actually no need to do that test (because we already know that it will always fail).

If you are working with Objective-C APIs and types on the other hand, there may be occasions where you will need to test for type, this is a good example of testing for type in an Objective-C collection that has items of different types:

let userDefaults = NSUserDefaults.standardUserDefaults()
let lastRefreshDate: AnyObject? = userDefaults.objectForKey("LastRefreshDate")
if let date = lastRefreshDate as? NSDate {
print("\(date.timeIntervalSinceReferenceDate)")
}

Hope this helps.

3 Comments

This works when there are items in the Collection, but not if it's empty.
Hmm, I see what you mean now. One way you could check that could be this: if obj.dynamicType == [Int]().dynamicType { print("type matches") }
No luck with that. I also tried prop.isEqual([String]()) and prop.isEqual([Int]()) which both return true if the Array is empty.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.