简体   繁体   中英

Comparing NSNumber property wrapping NS_ENUM in Swift without using rawValue

We have some existing code in ObjC that does JSON serialization/deserialization. In one of these data object's .h file, we have something like:

DataObject.h

@class DataObject
typedef NS_ENUM(NSInteger, FriendStatus)
{
    FriendStatusMyself = -1,
    FriendStatusNotFriends = 0,
    FriendStatusFriends = 1,
    FriendStatusPendingIncoming = 2,
    FriendStatusPendingOutgoing = 3
};

@interface DataObject : MTLModel <MTLJSONSerializing>

@property (nonatomic, strong) NSNumber *friendStatus;
// more stuff...
@end

Now this works great with JSON serialization and all is right with the world. Well somewhat.

In my swift class, I want to use the DataObject, but reference friendStatus as a FriendStatus enum, so I end up using .rawValue a lot. For example

RandomClass.swift

if (dataObject.friendStatus == FriendStatus.PendingIncoming.rawValue) {
    // do something
}

This works, and arguably this is relatively minor, but using .rawValue all over the place seems yucky (tm) . Is there a way to do a conversion so DataObject.friendStatus is truly a FriendStatus enum and I can stop using .rawValue in swift?

Unfortunately, I'm limited in the changes I can make on my model (DataObject) since it's existing code.

Because NSNumber is not the same as NSInteger . NSNumber is a reference type, while NSInteger is a value type, which resolves to Int32 or Int64 depending on your platform.

Tell Swift how to compare an NSNumber with a FriendStatus :

public func == (lhs: NSNumber, rhs: FriendStatus) -> Bool {
    return lhs.integerValue == rhs.rawValue
}

public func == (lhs: FriendStatus, rhs: NSNumber) -> Bool {
    return rhs.integerValue == lhs.rawValue
}

You could define an extension for the DataObject class that defines a getter to do the unwrapping for you.

extension DataObject {
    var friendStatusEnum: FriendStatus {
        return FriendStatus(rawValue: friendStatus.integerValue)!
    }
}

Note that it implicitly unwraps the enum, which means if for some reason the NSNumber has a value that doesn't match the enum it will crash. A more robust version would check for nil from the init and return a sensible default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM