Compare parameter of type Any [duplicate] - swift

I'm working with the Mirror in swift, I found Mirror.Child is very strange, the label is nullable, but the value seems not nullable.
public typealias Child = (label: String?, value: Any)
I don't know how to check if the value is nil or not.
let b: Bool? = true
let a: Any = b
print(a == nil) // false
I have one solution:
print(String(describing: a) == "nil") // true
but it is obviously not a good solution.
what is the best way to check if a is nil or not ?
Let me put more detail,
let mirror = Mirror(reflecting: object) // object can be any object.
for child in mirror.children {
guard let label = child.label else {
continue
}
// how to check if the value is nil or not here ?
setValue(child.value, forKey: label)
}

Using if case:
You can use if case Optional<Any>.none = a to test if a is nil:
var b: Bool?
var a = b as Any
if case Optional<Any>.none = a {
print("nil")
} else {
print("not nil")
}
nil
b = true
a = b as Any
if case Optional<Any>.none = a {
print("nil")
} else {
print("not nil")
}
not nil
Using switch:
You can use the pattern test with switch as well:
var b: Bool?
var a = b as Any
switch a {
case Optional<Any>.none:
print("nil")
default:
print("not nil")
}
nil

Related

Accessing the optional value of a PartialKeyPath in Swift 4

Using the PartialKeyPath API, how can you access a value of a key path's reference? For example, this works for non-optional values, but not with Optional values.
The issue I'm having is that self[keyPath: keyPath] returns a non-optional Any value.
struct Element {
let name: String
let mass: Double?
func stringValue(_ keyPath: PartialKeyPath<Element>) -> String {
let value = self[keyPath: keyPath]
switch value {
case let string as String:
return string.capitalized
case nil:
return "N/A"
case let value:
return String(describing: value)
}
}
}
let element = Element(name: "Helium", mass: 4.002602)
let string = element.stringValue(\Element.mass) /* Optional(4.002602) */
The result is that case nil is never executed and the last case is being printed as Optional(value).
How can I unwrap value properly to extract the optional?
The solution was to use Mirror to unwrap the optional which seems less than optimal. Looking forward to better Reflection support in Swift!
func unwrap(_ value: Any) -> Any? {
let mirror = Mirror(reflecting: value)
if mirror.displayStyle != .optional {
return value
}
if let child = mirror.children.first {
return child.value
} else {
return nil
}
}
struct Element {
let name: String
let mass: Double?
func stringValue(_ keyPath: PartialKeyPath<AtomicElement>) -> String {
guard let value = unwrap(self[keyPath: keyPath]) else {
return "N/A"
}
switch value {
case let string as String:
return string.capitalized
default:
return String(describing: value)
}
}
}
let element = Element(name: "Helium", mass: 4.002602)
let string = element.stringValue(\Element.mass) /* 4.002602 */

How can I check if a property has been set using Swift reflection?

Some of my models have optional properties. I'm trying to write a method that can evaluate if they've been set.
Below is an attempt, but I can't figure out how to determine a nil value from an Any object [edit: (the child variable is of type Any)]. It doesn't compile.
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
let value = child.value
if let optionalValue = value as? AnyObject? { //Does not compile
if optionalValue == nil {
return false
}
}
}
return true
}
Edit:
I forgot to clarify that the child value in the above example is always of type Any. The Any type is difficult in that it cannot be compared to nil and a cast to AnyObject always fails. I've tried to illustrate it in the playground below.
var anyArray = [Any]();
var optionalStringWithValue: String? = "foo";
anyArray.append(optionalStringWithValue);
var nilOptional: String?
anyArray.append(nilOptional)
print(anyArray[0]); // "Optional("foo")\n"
print(anyArray[1]); // "nil\n"
if let optionalString = anyArray[0] as? AnyObject {
//will always fail
print("success")
}
//if anyArray[1] == nil { // will not compile
//}
I used #ebluehands technique of reflecting the Any value to modify the original function. It cycles through the properties with an initial mirror, then reflects each one individually using displayStyle to determine if the property is optional.
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
let value: Any = child.value
let subMirror = Mirror(reflecting: value)
if subMirror.displayStyle == .Optional {
if subMirror.children.count == 0 {
return false
}
}
}
return true
}
Obsolete:
You can simply check if the optional value is nil or not :
func allPropertiesHaveValues(obj: AnyObject) -> Bool {
let mirror = Mirror(reflecting: obj)
for child in mirror.children {
//child.value being an optional
if child.value == nil {
return false
}
}
return true
}
Edit:
To check if an Any object is optional and contains a value or not using reflection :
let optionalString : String? = "optional string"
let any : Any = optionalString
//First you will need to create a mirror of the any object
let mirror = Mirror(reflecting : any)
//Then you can check the display style to see if it's an optional
if mirror.displayStyle == .Optional {
//If it is, check the count of its children to see if there is a value or not
if mirror.children.count == 0 {
print("I don't have a value")
}
else {
print("I have a value")
}
}
Here is a playground example (based on yours):
var anyArray = [Any]()
var optionalStringWithValue: String? = "foo"
anyArray.append(optionalStringWithValue)
var nilOptional: String?
anyArray.append(nilOptional)
let string = "string not optional"
anyArray.append(string)
print(anyArray[0]) // "Optional("foo")\n"
print(anyArray[1]) // "nil\n"
print(anyArray[2]) // "string not optional\n"
let mirrorOptionalWithValue = Mirror(reflecting: anyArray[0])
if mirrorOptionalWithValue.displayStyle == .Optional
&& mirrorOptionalWithValue.children.count == 1 {
print("Is an optional and contains a value")
}
let mirrorOptionalWithoutValue = Mirror(reflecting: anyArray[1])
if mirrorOptionalWithoutValue.displayStyle == .Optional &&
mirrorOptionalWithoutValue.children.count == 0 {
print("Is an optional but is nil")
}
let mirrorNotAnOptional = Mirror(reflecting: anyArray[2])
if mirrorNotAnOptional.displayStyle != .Optional {
print("Is not an optional")
}
Another option is create a extension.
extension NSManagedObject {
func checkIfAllRequiredMembersAreSet() -> Bool {
let attributes = self.entity.attributesByName
for (attribute, value) in attributes {
if value.attributeValueClassName != nil {
let v: AnyObject? = self.valueForKey(attribute)
if !value.optional && v != nil {
return false
}
}
}
return true
}
}
Based on this answer, I recommend using if case Optional<Any>.some(_).
I did something recently to make sure I have at least one optional set. Here's an example to make sure all are set. You can paste into playgrounds:
import Foundation
struct SomeError: Error {
let code: Int?
let message: String?
let errorDescription: String?
var allValuesSet: Bool {
for aChild in Mirror(reflecting: self).children {
if case Optional<Any>.some(_) = aChild.value {
continue
} else {
return false
}
}
return true
}
}
let errorTest = SomeError(code: nil, message: "failed", errorDescription: nil)
let errorTest2 = SomeError(code: -1, message: "failed", errorDescription: "missing information")
print("is valid: \(errorTest.allValuesSet)") //is valid: false
print("is valid: \(errorTest2.allValuesSet)") //is valid: true

Casting to generic optional in Swift

I'm fiddling around with generics in Swift and hit something I can't figure out: If I cast a value into the type of a generic parameter, the cast is not performed. If I try the same with static types, it works.
class SomeClass<T> {
init?() {
if let _ = 4 as? T {
println("should work")
} else {
return nil
}
}
}
if let _ = SomeClass<Int?>() {
println("not called")
}
if let _ = 4 as? Int? {
println("works")
}
Can anybody explain this behavior? Shouldn't be both cases equivalent?
Update
The above example is simplified to the max. The following example illustrates the need for a cast a little better
class SomeClass<T> {
init?(v: [String: AnyObject]) {
if let _ = v["k"] as? T? {
print("should work")
} else {
print("does not")
return nil
}
}
}
if let _ = SomeClass<Int?>(v: ["k": 4]) {
print("not called")
}
if let _ = SomeClass<Int>(v: ["k": 4]) {
print("called")
}
2nd Update
After #matt made me learn about AnyObject and Any and #Darko pointed out in his comments how dictionaries make my example too complicated, here's my next refinement
class SomeClass<T> {
private var value: T!
init?<U>(param: U) {
if let casted = param as? T {
value = casted
} else {
return nil
}
}
}
if let _ = SomeClass<Int?>(param: Int(4)) {
println("not called")
}
if let _ = SomeClass<Int>(param: Int(4)) {
println("called")
}
if let _ = Int(4) as? Int? {
println("works")
}
if let _ = (Int(4) as Any) as? Int? {
println("Cannot downcast from Any to a more optional type 'Int?'")
}
I tried using init?(param: Any) before, but that yields the same problem illustrated in the last if which is discussed elsewhere.
So all it comes down to: Has anyone really been far as to ever cast anything to a generic optional type? In any case? I'm happy to accept any working example.
This is really not about generics at all; it's about AnyObject (and how casting works). Consider:
let d = ["k":1]
let ok = d["k"] is Int?
print (ok) // true
// but:
let d2 = d as [String:AnyObject]
let ok2 = d2["k"] is Int?
print (ok2) // false, though "is Int" succeeds
Since your initializer casts the dictionary up to [String:AnyObject] you are in this same boat.
This works as expected now - in Playgrounds as well as in projects. Retested in Swift 5.4:
class SomeClass<T> {
private var value: T
init?<U>(param: U) {
if let casted = param as? T {
value = casted
} else {
return nil
}
}
}
if let _ = SomeClass<Int?>(param: Int(4)) {
print("called")
}
if let _ = SomeClass<Int>(param: Int(4)) {
print("called")
}
which prints called two times as expected.
As far I can see the goal of your updated code is to find out if the passed parameter (the value of the dict) is of type T. So you are mis-using the as? cast to check the type. What you actually want is the "is" operator.
class SomeClass<T> {
init?(v: [String: AnyObject]) {
if v["k"] is T {
print("called if AnyObject is of type T")
} else {
print("called if AnyObject is not of type T")
return nil
}
}
}
if let _ = SomeClass<Int>(v: ["k": 4]) {
print("called")
}
if let _ = SomeClass<Int?>(v: ["k": 4]) {
print("not called")
}

How to unwrap an optional value from Any type?

Given an array of [Any] that has a mix of optional and non optional values, e.g:
let int:Int? = 1
let str:String? = "foo"
let values:[Any] = [int,2,str,"bar"]
How can we extract the value of the Optional in the Any type (if there is one) so we can create a generic print function that only prints out the values.
E.g. this printArray function goes through and prints each element:
func printArray(values:[Any]) {
for i in 0..<values.count {
println("value[\(i)] = \(values[i])")
}
}
printArray(values)
Which will output:
value[0] = Optional(1)
value[1] = 2
value[2] = Optional("foo")
value[3] = bar
How can we change it so it only prints the underlying value so that it unwraps the value if it's Optional? e.g:
value[0] = 1
value[1] = 2
value[2] = foo
value[3] = bar
Update Progress...
It can work when changing the argument to [Any?], e.g:
let values:[Any?] = [int,2,str,"bar"]
func printArray(values:[Any?]) {
for i in 0..<values.count {
println("value[\(i)] = \(values[i]!)")
}
}
printArray(values)
Which will print the desired:
value[0] = 1
value[1] = 2
value[2] = foo
value[3] = bar
But would still like to see how we can unwrap an Optional from Any as this is what MirrorType.value returns making it difficult to extract the Optional value, e.g:
class Person {
var id:Int = 1
var name:String?
}
var person = Person()
person.name = "foo"
var mt:MirrorType = reflect(person)
for i in 0 ..< mt.count {
let (name, pt) = mt[i]
println("\(name) = \(pt.value)")
}
Prints out:
id = 1
name = Optional("foo")
When I need:
id = 1
name = foo
For Xcode 7 and Swift 2:
func unwrap(any:Any) -> Any {
let mi = Mirror(reflecting: any)
if mi.displayStyle != .Optional {
return any
}
if mi.children.count == 0 { return NSNull() }
let (_, some) = mi.children.first!
return some
}
let int:Int? = 1
let str:String? = "foo"
let null:Any? = nil
let values:[Any] = [unwrap(int),2,unwrap(str),"bar", unwrap(null)]
This will give you [1, 2, "foo", "bar", {NSObject}]
Change NSNull() to nil and the return value of unwrap func to Any? will always unwrap any type.
To maybe save somebody from cobbling it all together from the answers and comments, here is an answer including both "sane" ways and some what I consider to be improvements for Swift 3 coming with Xcode 8.2.1.
Using Reflection
func unwrap<T>(_ any: T) -> Any
{
let mirror = Mirror(reflecting: any)
guard mirror.displayStyle == .optional, let first = mirror.children.first else {
return any
}
return first.value
}
Discussion
The accepted answer from bubuxu fails to compile with Swift 3.
As walkline suggests in his comment, changing .Optional to .optional fixes this (see SE-0005 and Swift API Design Guidelines).
Reasons I thought this solution can be improved:
I find returning NSNull() weird.
I think the alternative of returning nil with return type Any? is also problematic because it turns everything (including non-optional values) into optional values
(e.g. unwrap(any: 42) returns Optional(42)).
When calling unwrap(any:) with anything but an Any value (any more any anybody?) the Swift 3 compiler warns about implicitly
coercing to Any.
Similiar thoughts apply to Sajjon's answer.
The solution I suggest addresses all those points. Be aware however that unwrap(_:) returns nil as type Any so using the nil
coalescing operator does not work anymore. This means that this just shifts around what I think is problematic about the second point. But I found this to be just the right thing to do for the (to me) more interesting use case regarding reflection.
Using an Extension on Optional
protocol OptionalProtocol {
func isSome() -> Bool
func unwrap() -> Any
}
extension Optional : OptionalProtocol {
func isSome() -> Bool {
switch self {
case .none: return false
case .some: return true
}
}
func unwrap() -> Any {
switch self {
case .none: preconditionFailure("trying to unwrap nil")
case .some(let unwrapped): return unwrapped
}
}
}
func unwrapUsingProtocol<T>(_ any: T) -> Any
{
guard let optional = any as? OptionalProtocol, optional.isSome() else {
return any
}
return optional.unwrap()
}
Discussion
This is bascially LopSae's solution updated to Swift 3. I also changed the precondition failure message and added unwrapUsingProtocol(_:).
Usage
class Person {
var id:Int = 1
var name:String?
}
var person = Person()
person.name = "foo"
let mirror = Mirror(reflecting: person)
for child in mirror.children.filter({ $0.label != nil }) {
print("\(child.label!) = \(unwrap(child.value))")
}
No matter if you're using unwrap() or unwrapUsingProtocol(), this will print
id = 1
name = foo
If you're looking for a way to neatly align the output, see Is there a way to use tabs to evenly space out description strings in Swift?
To check if a Any variable is an optional a protocol can be used as a means of a typeless Optional.
Just as its currently imposible (as of Swift 2) to check against a typeless Optional it is also not posible to cast an into a typeless optional:
let anyType: Any.Type = Optional<String>.self
let anyThing: Any = Optional.Some("string")
anyType is Optional.Type // Causes error
let maybeString = anything as? Optional // Also causes error
// Argument for generic parameter 'Wrapped' could not be inferred
However, the proposed OptionalProtocol can also be used to provide a generic-less interface to access the Optional values and even unwrap them:
protocol OptionalProtocol {
func isSome() -> Bool
func unwrap() -> Any
}
extension Optional : OptionalProtocol {
func isSome() -> Bool {
switch self {
case .None: return false
case .Some: return true
}
}
func unwrap() -> Any {
switch self {
// If a nil is unwrapped it will crash!
case .None: preconditionFailure("nill unwrap")
case .Some(let unwrapped): return unwrapped
}
}
}
// With this we can check if we have an optional
let maybeString: String? = "maybe"
let justString: String = "just"
maybeString is OptionalProtocol // true
justString is OptionalProtocol // false
With the methods provided the optionals can be checked and accessed in quite a natural way, without needing the impossible cast to Optional:
let values:[Any] = [
Optional.Some(12),
2,
Optional<String>.None, // a "wrapped" nil for completeness
Optional.Some("maybe"),
"something"
]
for any in values {
if let optional = any as? OptionalProtocol {
if optional.isSome() {
print(optional.unwrap())
} else {
// nil should not be unwrapped!
print(optional)
}
continue
}
print(any)
}
Which will print:
12
2
nil
maybe
something
Slight alteration on #thm to completely unwrap:
func unwrap<T>(_ any: T) -> Any {
let mirror = Mirror(reflecting: any)
guard mirror.displayStyle == .optional, let first = mirror.children.first else {
return any
}
return unwrap(first.value)
}
I think this is a kind of bug.
In general, to discover and extract the specific type from Any, down casting with as is the only supported method. But :
let int:Int? = 1
let any:Any = int
switch any {
case let val as Optional<Int>: // < [!] cannot downcast from 'Any' to a more optional type 'Optional<Int>'
print(val)
default:
break
}
This means, there is no supported way to do that.
Anyway, apparently you can do that with reflect:
func printArray(values:[Any]) {
for i in 0..<values.count {
var val = values[i]
var ref = reflect(val)
// while `val` is Optional and has `Some` value
while ref.disposition == .Optional && ref.count > 0 && ref[0].0 == "Some" {
// replace `val` with unwrapped value
val = ref[0].1.value;
ref = reflect(val)
}
println("value[\(i)] = \(val)")
}
}
let int:Int? = 1
let str:String? = "foo"
let values:[Any] = [int,2,str,"bar"]
printArray(values)
outputs:
value[0] = 1
value[1] = 2
value[2] = foo
value[3] = bar
ADDED: minor tweaked version
func printArray(values:[Any]) {
for i in 0..<values.count {
var ref = reflect(values[i])
// while `val` is Optional and has `Some` value
while ref.disposition == .Optional && ref.count > 0 && ref[0].0 == "Some" {
// Drill down to the Mirror of unwrapped value
ref = ref[0].1
}
let val = ref.value
println("value[\(i)] = \(val)")
}
}
Factoring out into a function:
func unwrapAny(val:Any) -> Any {
var ref = reflect(val)
while ref.disposition == .Optional && ref.count > 0 && ref[0].0 == "Some" {
ref = ref[0].1
}
return ref.value
}
func printArray(values:[Any]) {
for i in 0..<values.count {
println("value[\(i)] = \(unwrapAny(values[i]))")
}
}
Not a complete answer. It boils down to this:
let int:Int? = 1
let str:String? = "foo"
let values:[Any] = [int,2,str,"bar"]
func printArray(values:[Any]) {
for i in 0..<values.count {
let v = values[i]
if _stdlib_demangleName(_stdlib_getTypeName(v)) == "Swift.Optional" {
println("value[\(i)] = "it's optional: \(v)") // here I'm stuck
}else {
println("value[\(i)] = \(values[i])")
}
}
}
printArray(values)
how about this solution, I made a generic version of previous answer.
fileprivate func unwrap<T>(value: Any)
-> (unwraped:T?, isOriginalType:Bool) {
let mirror = Mirror(reflecting: value)
let isOrgType = mirror.subjectType == Optional<T>.self
if mirror.displayStyle != .optional {
return (value as? T, isOrgType)
}
guard let firstChild = mirror.children.first else {
return (nil, isOrgType)
}
return (firstChild.value as? T, isOrgType)
}
let value: [Int]? = [0]
let value2: [Int]? = nil
let anyValue: Any = value
let anyValue2: Any = value2
let unwrappedResult:([Int]?, Bool)
= unwrap(value: anyValue) // ({[0]}, .1 true)
let unwrappedResult2:([Int]?, Bool)
= unwrap(value: anyValue2) // (nil, .1 true)
let unwrappedResult3:([UInt]?, Bool)
= unwrap(value: anyValue) // (nil, .1 false)
let unwrappedResult4:([NSNumber]?, Bool)
= unwrap(value: anyValue) ({[0]}, .1 false)
The following is code on Playground.
Based on the solution by #bubuxu, one can also:
func unwrap<T: Any>(any: T) -> T? {
let mirror = Mirror(reflecting: any)
guard mirror.displayStyle == .optional else { return any }
guard let child = mirror.children.first else { return nil }
return unwrap(any: child.value) as? T
}
But you need to check against nil using ?? nil when using unwrap, as done in foo
func foo<T>(_ maybeValue: T?) {
if let value: T = unwrap(any: maybeValue) ?? nil {
print(value)
}
}
Still neat though!
(Anyone got a solution for the ?? nil check?)
Without making it too complicated, why not:
let int:Int? = 1
let str:String? = "foo"
let values:[Any?] = [int,2,str,"bar"]
for var i:Int = 0; i < values.count; i++
{
println("\(values[i]!)")
}
This prints:
1
2
foo
bar
According to Using Enumeration case patterns in Swift 2.0
those might be look like this:
let pattern :[Int?] = [nil, 332, 232,nil,55]
for case let number? in pattern {
print(number)
}
Output:
332,
232,
55

How to check object is nil or not in swift?

Suppose I have String like :
var abc : NSString = "ABC"
and I want to check that it is nil or not and for that I try :
if abc == nil{
//TODO:
}
But this is not working and giving me an error. Error Says :
Can not invoke '=='with an argument list of type '(#|value NSString , NilLiteralConvertible)'
Any solution for this?
If abc is an optional, then the usual way to do this would be to attempt to unwrap it in an if statement:
if let variableName = abc { // If casting, use, eg, if let var = abc as? NSString
// variableName will be abc, unwrapped
} else {
// abc is nil
}
However, to answer your actual question, your problem is that you're typing the variable such that it can never be optional.
Remember that in Swift, nil is a value which can only apply to optionals.
Since you've declared your variable as:
var abc: NSString ...
it is not optional, and cannot be nil.
Try declaring it as:
var abc: NSString? ...
or alternatively letting the compiler infer the type.
The case of if abc == nil is used when you are declaring a var and want to force unwrap and then check for null. Here you know this can be nil and you can check if != nil use the NSString functions from foundation.
In case of String? you are not aware what is wrapped at runtime and hence you have to use if-let and perform the check.
You were doing following but without "!". Hope this clears it.
From apple docs look at this:
let assumedString: String! = "An implicitly unwrapped optional string."
You can still treat an implicitly unwrapped optional like a normal optional, to check if it contains a value:
if assumedString != nil {
println(assumedString)
}
// prints "An implicitly unwrapped optional string."
The null check is really done nice with guard keyword in swift. It improves the code readability and the scope of the variables are still available after the nil checks if you want to use them.
func setXYX -> Void{
guard a != nil else {
return;
}
guard b != nil else {
return;
}
print (" a and b is not null");
}
I ended up writing utility function for nil check
func isObjectNotNil(object:AnyObject!) -> Bool
{
if let _:AnyObject = object
{
return true
}
return false
}
Does the same job & code looks clean!
Usage
var someVar:NSNumber?
if isObjectNotNil(someVar)
{
print("Object is NOT nil")
}
else
{
print("Object is nil")
}
func isObjectValid(someObject: Any?) -> Any? {
if someObject is String {
if let someObject = someObject as? String {
return someObject
}else {
return ""
}
}else if someObject is Array<Any> {
if let someObject = someObject as? Array<Any> {
return someObject
}else {
return []
}
}else if someObject is Dictionary<AnyHashable, Any> {
if let someObject = someObject as? Dictionary<String, Any> {
return someObject
}else {
return [:]
}
}else if someObject is Data {
if let someObject = someObject as? Data {
return someObject
}else {
return Data()
}
}else if someObject is NSNumber {
if let someObject = someObject as? NSNumber{
return someObject
}else {
return NSNumber.init(booleanLiteral: false)
}
}else if someObject is UIImage {
if let someObject = someObject as? UIImage {
return someObject
}else {
return UIImage()
}
}
else {
return "InValid Object"
}
}
This function checks any kind of object and return's default value of the kind of object, if object is invalid.
if (MyUnknownClassOrType is nil) {
println("No class or object to see here")
}
Apple also recommends that you use this to check for depreciated and removed classes from previous frameworks.
Here's an exact quote from a developer at Apple:
Yes. If the currently running OS doesn’t implement the class then the class method will return nil.
Hope this helps :)
Normally, I just want to know if the object is nil or not.
So i use this function that just returns true when the object entered is valid and false when its not.
func isNotNil(someObject: Any?) -> Bool {
if someObject is String {
if (someObject as? String) != nil {
return true
}else {
return false
}
}else if someObject is Array<Any> {
if (someObject as? Array<Any>) != nil {
return true
}else {
return false
}
}else if someObject is Dictionary<AnyHashable, Any> {
if (someObject as? Dictionary<String, Any>) != nil {
return true
}else {
return false
}
}else if someObject is Data {
if (someObject as? Data) != nil {
return true
}else {
return false
}
}else if someObject is NSNumber {
if (someObject as? NSNumber) != nil{
return true
}else {
return false
}
}else if someObject is UIImage {
if (someObject as? UIImage) != nil {
return true
}else {
return false
}
}
return false
}
Swift 4.2
func isValid(_ object:AnyObject!) -> Bool
{
if let _:AnyObject = object
{
return true
}
return false
}
Usage
if isValid(selectedPost)
{
savePost()
}
Swift short expression:
var abc = "string"
abc != nil ? doWork(abc) : ()
or:
abc == nil ? () : abc = "string"
or both:
abc != nil ? doWork(abc) : abc = "string"
Swift-5 Very Simple Way
//MARK:- In my case i have an array so i am checking the object in this
for object in yourArray {
if object is NSNull {
print("Hey, it's null!")
}else if object is String {
print("Hey, it's String!")
}else if object is Int {
print("Hey, it's Int!")
}else if object is yourChoice {
print("Hey, it's yourChoice!")
}
else {
print("It's not null, not String, not yourChoice it's \(object)")
}
}
Swift 4
You cannot compare Any to nil.Because an optional can be nil and hence it always succeeds to true.
The only way is to cast it to your desired object and compare it to nil.
if (someone as? String) != nil
{
//your code`enter code here`
}
Swift 5
Crash
Your app crash because parameters receive null, and broke in NSException.
if let parameters = parameters {
httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
}
Solution
if let parameters = parameters, JSONSerialization.isValidJSONObject(parameters) {
httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
}