Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile time key path checking in Swift

Tags:

swift

When I'm implementing NSCoding protocol in Objective-C, I'd like to use NSStringFromSelector(@selector(name)) to get the key path of a property, like below

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.accountName forKey:NSStringFromSelector(@selector(accountName))];
    [aCoder encodeObject:self.userId forKey:NSStringFromSelector(@selector(userId))];
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        _accountName = [aDecoder decodeObjectForKey:forKey:NSStringFromSelector(@selector(accountName))];
        _userId = [aDecoder decodeObjectForKey:forKey:NSStringFromSelector(@selector(userId))];
    }
    return self;
}

I like this way because it prevents from mistyping without the need to define lots of string constants, and I will get warnings if I renamed those properties. But I couldn't find a way to do this in Swift, any ideas?

like image 912
Pride Chung Avatar asked Jun 09 '14 16:06

Pride Chung


1 Answers

In Swift, selectors are strings. (Well, there's the Selector type, but that transparently converts to and from String.) So you can omit NSStringFromSelector and @selector and just use a string literal.

If you're looking to introspect the names of your properties... it's a bit tougher. Using reflect() on an instance of your class returns an object of type Mirror. (Paste one of those symbols in your playground and cmd-click to get the declarations in the standard library "header".) You can use that to walk the class's list of properties.

This would make your "encode everything" method look something like this:

func encodeWithCoder(coder: NSCoder!) {
    let mirror = reflect(self)
    let (accountNameKey, _) = mirror[0]
    let (userIdKey, _) = mirror[1]

    coder.encodeObject(accountName, forKey: accountNameKey)
    coder.encodeObject(userId, forKey: userIdKey)
}

It's not ideal, since you have to know the order of the properties' definitions. But it might be improved upon...

like image 181
rickster Avatar answered Nov 07 '22 11:11

rickster