Reputation: 121
I'm currently porting an iOS app from Objective-C to Swift. While doing that I just stumbled across a problem I'm struggling with.
I have a variable ("value") which can bet set to AnyObject?, especially can it be of type String, Array, Dictionary and Set. Now, in my previous code I was testing my "value" variable for its value's type in order to further work with it:
id value = [myDatahandler getValue];
if (([value isKindOfClass:[NSSet class]] || [value isKindOfClass:[NSArray class]]) && [value count] > 0) {
// do something
}
Trying to do the same in Swift seems not to work...
var value: AnyObject? = myDatahandler.getValue()
if (value is Set || value is Array) && value!.count > 0 {
// Error:
// Generic parameter 'Element' could not be inferred in cast to 'Array'
// Generic parameter 'Element' could not be inferred in cast to 'Set'
}
After a couple of hours searching for the right way to do this but not finding anything helpful, I hope the community can come to my rescue here...
Any suggestions how this could work?
Upvotes: 0
Views: 929
Reputation: 235
Use Any
rather than AnyObject
because from HackingWithSwift page
AnyObject refers to any instance of a class, and is equivalent to id in Objective-C. It’s useful when you specifically want to work with a reference type, because it won’t allow any of Swift’s structs or enums to be used. AnyObject is also used when you want to restrict a protocol so that it can be used only with classes.
Any refers to any instance of a class, struct, or enum – literally anything at all. You’ll see this in Swift wherever types are unknown or are mixed in ways that can be meaningfully categorized:
Then, you can use a guard for unwrapping an optional value
guard let value = myDatahandler.getValue() as? [YourClass], !value.isEmpty {
return
}
Upvotes: 1
Reputation: 1562
The problem is that Set
and Array
are both generic types. You must provide the element type.
For example, if you're expect they contain Strings
:
if (value is Set<String> || value is Array<String>) && value!.count > 0 {
}
If you just care that it's an array or set (and you don't care about the element type), you could use Any
as the element type:
if (value is Set<Any> || value is Array<Any>) && value!.count > 0 {
}
Upvotes: 0
Reputation: 2908
I feel like you can use a guard to do this.. Hope the following piece of code works.
guard let value = myDatahandler.getValue() as? [Element] , value.count > 0 else {
return
}
print(value)
Upvotes: 1