5

Variations of this question have been asked here and here, but it appears that the question hasn't received a clear answer.

The problem that I face is that the MPMediaLibrary framework keeps a reference to each MPMediaItem (music, video, podcast, ...) as an usigned long long (uint64_t), but I can't seem to find a way to store this value using Core Data. Using Integer 64 as the data type doesn't seem to do the trick and I don't see an alternative.

Community
  • 1
  • 1
Bart Jacobs
  • 8,812
  • 7
  • 41
  • 83

2 Answers2

7

Since there's no support for unsigned long long in Core Data you might need to literally "do the trick" yourself.

One of the ideas is to store the value as ...binary data, and define custom accessors that return the data as uint64_t:

// header
@interface Event : NSManagedObject

@property (nonatomic, retain) NSData * timestamp;

- (void)setTimestampWithUInt64:(uint64_t)timestamp;
- (uint64_t)timestampUInt64;

@end


// implementation
@implementation Event

@dynamic timestamp;

- (void)setTimestampWithUInt64:(uint64_t)timestamp
{
    self.timestamp = [NSData dataWithBytes:&timestamp length:sizeof(timestamp)];
}

- (uint64_t)timestampUInt64
{
    uint64_t timestamp;
    [self.timestamp getBytes:&timestamp length:sizeof(timestamp)];
    return timestamp;
}

@end

It seems to do the job. The code below:

Event *event = [NSEntityDescription insertNewObjectForEntityForName:@"Event"
                inManagedObjectContext:self.managedObjectContext];

uint64_t timestamp = 119143881477165;
NSLog(@"timestamp: %llu", timestamp);

[event setTimestampWithUInt64:timestamp];
[self.managedObjectContext save:nil];

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Event"];
Event *retrievedEvent = [[self.managedObjectContext executeFetchRequest:request
                           error:nil] lastObject];
NSLog(@"timestamp: %llu", [retrievedEvent timestampUInt64]);

Outputs:

2012-03-03 15:49:13.792 ulonglong[9672:207] timestamp: 119143881477165
2012-03-03 15:49:13.806 ulonglong[9672:207] timestamp: 119143881477165

A hack like this of course adds a level of indirection, and it may affect performance when timestamp is heavily used.

ayoy
  • 3,755
  • 17
  • 20
  • Thanks very much for taking the time to submit this detail answer, @ayoy. NSData was an option that I considered, but I was a bit surprised to find out that unsigned long long values are not supported by Core Data out of the box. Anyway, your solution works perfectly fine. – Bart Jacobs Mar 03 '12 at 17:09
1

While the context in this case is super late, I'm sure I'm not the only one that will stumble upon it. In the case of the MPMediaLibrary, storing the ID as a NSString instead:

ie:

[NSString stringWithFormat:@"%@", [currentMediaItem valueForProperty:MPMediaEntityPropertyPersistentID]];
Charles J
  • 11
  • 1