Realm.io - primary connection key in objective-c

I am trying to find a way to combine multiple properties into a primary key using Realm.io and Objective-c.

Take this object as an example:

@interface Beacon : RLMObject

@property NSString *uuid;
@property int major;
@property int minor;

@end

RLM_ARRAY_TYPE(Beacon)

How can I then combine, for example. uuid, major and minor into one primary key?

+4
source share
2 answers

Objective-C . , ignoredProperties . , Swift, , , ObjC, , , . , KVO , Realm , Realm, , , . KVO, , , Apple.

CompositeKeyObject.h:

@interface CompositeKeyObject : RLMObject

@property (nonatomic, strong) NSString* partOne;
@property (nonatomic, strong) NSString* partTwo;

@end

CompositeKeyObject.m:

@interface CompositeKeyObject ()

@property (nonatomic, strong) NSString* partOneValue;
@property (nonatomic, strong) NSString* partTwoValue;
@property (nonatomic, strong) NSString* compositeKey;

@end

@implementation CompositeKeyObject

- (instancetype)initWithValue:(id)value
{
    // Need to make a copy and set the correct "value" properties.
    // Otherwise, the object won't be created properly. 
    NSMutableDictionary* valueCopy = [value mutableCopy];
    if(valueCopy[@"partOne"] != nil) {
        valueCopy[@"partOneValue"] = valueCopy[@"partOne"];
    }
    if(valueCopy[@"partTwo"] != nil) {
        valueCopy[@"partTwoValue"] = valueCopy[@"partTwo"];
    }

    self = [super initWithValue:[valueCopy copy]];
    if(self != nil) {
        // Make sure primary key is in sync.
        [self updatePrimaryKey];
    }
    return self;
}

- (void)setPartOne:(NSString *)partOne
{
    self.partOneValue = partOne;
    [self updatePrimaryKey];
}

- (void)setPartTwo:(NSString *)partTwo
{
    self.partTwoValue = partTwo;
    [self updatePrimaryKey];
}

- (NSString*)partOne
{
    return self.partOneValue;
}

- (NSString*)partTwo
{
    return self.partTwoValue;
}

- (void)updatePrimaryKey
{
    self.compositeKey = [NSString stringWithFormat:@"%@ <><><> %@", self.partOne, self.partTwo];
}

+ (NSString *)primaryKey
{
    return @"compositeKey";
}

+ (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args {
    predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partOne" withString:@"partOneValue"];
    predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partTwo" withString:@"partTwoValue"];
    return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
}

+ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat args:(va_list)args {
    predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partOne" withString:@"partOneValue"];
    predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partTwo" withString:@"partTwoValue"];
    return [self objectsInRealm:realm withPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
}

@end

:

- (void)testCompositeObject
{
    CompositeKeyObject* object = [[CompositeKeyObject alloc] init];
    object.partOne = @"ONE";
    object.partTwo = @"TWO";

    RLMRealm* realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
        [realm addObject:object];
    }];

    XCTAssertNotNil([CompositeKeyObject objectForPrimaryKey:@"ONE <><><> TWO"]);

    object = [[CompositeKeyObject alloc] init];
    object.partOne = @"ONE";
    object.partTwo = @"TWO";

    [realm transactionWithBlock:^{
        XCTAssertThrows([realm addObject:object]);
    }];
}

- (void)testCompositeObject2
{
    CompositeKeyObject* object = [[CompositeKeyObject alloc] initWithValue:@{@"partOne": @"ONE", @"partTwo": @"TWO"}];

    RLMRealm* realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
        [realm addObject:object];
    }];

    XCTAssertNotNil([CompositeKeyObject objectForPrimaryKey:@"ONE <><><> TWO"]);
    object = [[CompositeKeyObject alloc] initWithValue:@{@"partOne": @"ONE", @"partTwo": @"TWO"}];

    [realm transactionWithBlock:^{
        XCTAssertThrows([realm addObject:object]);
    }];
}
+2

, , . , .

ObjC , , , Swift, .

class Thing: Object {
    dynamic var part1: String = "" {
        didSet {
            self.updateCompoundKey()
        }
    }
    dynamic var part2: String = "" {
        didSet {
            self.updateCompoundKey()
        }
    }
    dynamic var compoundKey: String = ""

    override static func primaryKey() -> String? {
        return "compoundKey"
    }

    private func updateCompoundKey() {
        self.compoundKey= "\(self.part1)\(self.part2)"
    }
}
+1

All Articles