Search code examples
iosobjective-cswiftnsnumber

Swift 3 Creating an NSNumber Object


I'm trying to create an NSNumber Object. I have this codes in objc :

 @property (nonatomic, assign) Enum someEnum;

 static NSString *const value_type = @"type";

- (id)initWithDictionary:(NSDictionary *)dict andUID:(int)uid {
    self.someEnum = [[dict objectForKey:value_type] integerValue];
    }

- (NSDictionary *)serializeToDictionary {
    dict[value_type] = [NSNumber numberWithInteger:self.someEnum];
}

How this code would be equivalent in swift 3? I found that in swift NSNumber has init(value: ) symbol, but it just Initialize an object, not create and initialize. And that init(value: ) throws an error, that suggests to change "value" to "coder". My Swift code:

var someEnum = Enum.self

let value_type: NSString = "type"

 init(dictionary dict: NSDictionary, andUID uid: Int) {
    self.someEnum = dict.object(forKey: value_type) as! Enum.Type
}

 func serializeToDictionary() -> NSDictionary {
    dict[value_type] = NSNumber.init(value: self.someEnum)
}

Objective-C header file:

typedef enum {
    EnumDefault = 0,
    EnumSecond = 1
} Enum;

static NSString *const value_type = @"type";

@property (nonatomic, assign) Enum someEnum;

Objective C implementation file:

- (id)initWithDictionary:(NSDictionary *)dict andUID:(int)uid {
  if(self = [super init]) {
    self.someEnum = [[dict objectForKey:value_type] integerValue];
  }
  return self
}

- (NSDictionary *)serializeToDictionary {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[value_type] = [NSNumber numberWithInteger:self.someEnum];

    return dict;
}

Solution

  • var someEnum = Enum.self
    

    The value of someEnum is a Type, not a specific value. That's your first error.

    You want probably something like

    var someEnum: Enum = ... // (your default value)
    

    Now

    dict[value_type] = NSNumber.init(value: self.someEnum)
    

    Enums are not automatically converted to ints. Let's suppose Enum is backed by an Int value (which is not true for all enums). Than you can use:

    dict[value_type] = NSNumber(value: self.someEnum.rawValue)
    

    or just

    dict[value_type] = self.someEnum.rawValue as NSNumber
    

    Full code (it's not a good idea to use NS(Mutable)Dictionary in Swift and exceptional states which I solved using ! should be solved better).

    enum Enum : Int {
        case `default` = 0
        case second = 1
    }
    
    class Test {
        var someEnum: Enum = .default
        let valueType: String = "type"
    
        init(dictionary: NSDictionary, andUID uid: Int) {
            self.someEnum = Enum(rawValue: (dictionary[valueType] as! NSNumber).intValue) ?? .default
        }
    
        func serializeToDictionary() -> NSDictionary {
            let dictionary = NSMutableDictionary()
            dictionary[valueType] = self.someEnum.rawValue as NSNumber
    
            return dictionary
        }
    }