gujci
gujci

Reputation: 1284

How to decide whether a child is nil or not

I'm about to write a small protocol with a default extension which can decide if all parameters are set. (Swift 2.2)

My idea was to use the Mirror type and get all the child elements of the given type, than iterate through them. Like this:

var isComplete: Bool {
    get {
        return Mirror(reflecting: self).children.reduce(true) { return $0 && $1.value != nil } // <- Error, because value is not Optional
    }
}

The problem is in the type of the child, which is:

typealias Child = (label: String?, value: Any)

So i can't just check if it is nil, because it is not Optional. If is use print($1.value) it prints out nil, so there must be some pointer magic behind that.

Any ideas how to check the memory address of that. Or maybe some easier way to implement this functionality

Upvotes: 1

Views: 734

Answers (1)

gujci
gujci

Reputation: 1284

Ok, got the solution from https://stackoverflow.com/a/34637228/3308103

The point is that, we have to Mirror the value again and get it's children, which count is 1 if it has a value.

So the solution is hacky, but if anyone needs it...

public protocol OptionalValueObservable {
    var isComplete: Bool {get}
    var hasAnyProperty: Bool {get}
}

public extension OptionalValueObservable {
    var isComplete: Bool {
        get {
            return Mirror(reflecting: self).children.reduce(true) { acc, val in
                let subMirror = Mirror(reflecting: val.value)
                return acc && (subMirror.displayStyle == .Optional ? subMirror.children.count > 0 : true)
            }
        }
    }

    var hasAnyProperty: Bool {
        get {
            return Mirror(reflecting: self).children.reduce(false) { acc, val in 
                 let subMirror = Mirror(reflecting: val.value)
                 return acc || (subMirror.displayStyle == .Optional ? subMirror.children.count > 0 : true)
            }
        }
    }
}

Upvotes: 1

Related Questions