如何使用Realm存储NSURL数组?Realm模型存储媒体URL遇阻求解
Hey there! I've run into this exact issue before when working with Realm and media URLs, so let's break down how to fix it.
First, let's clarify why you're hitting roadblocks: Realm doesn't support storing NSURL directly (it's not one of Realm's supported primitive types), and you can't use a plain NSArray either—Realm requires array-like storage to use RLMArray, which only works with objects that inherit from RLMObject.
Here's the step-by-step solution:
We'll make a tiny helper class to convert your NSURL into a Realm-storable object by saving its absolute string representation.
// RLMURLObject.h #import <Realm/Realm.h> @interface RLMURLObject : RLMObject @property (nonatomic, copy) NSString *urlString; @end // Declare the RLMArray type for this object (required for Realm) RLM_ARRAY_TYPE(RLMURLObject)
// RLMURLObject.m #import "RLMURLObject.h" @implementation RLMURLObject // No extra code needed here unless you want to add validation @end
Modify your existing media model to include a RLMArray of our new RLMURLObject type:
// MediaModel.h #import <Realm/Realm.h> #import "RLMURLObject.h" @interface MediaModel : RLMObject // Your existing properties (image data, audio metadata, etc.) @property (nonatomic, strong) RLMArray<RLMURLObject *><RLMURLObject> *mediaURLs; @end @implementation MediaModel @end
When you have your array of NSURL instances, convert them to RLMURLObject instances first, then assign the array to your model:
// Example: You have an NSArray of NSURLs NSArray<NSURL *> *originalMediaURLs = @[/* your NSURL instances here */]; // Convert to RLMURLObject array NSMutableArray<RLMURLObject *> *realmURLObjects = [NSMutableArray array]; for (NSURL *url in originalMediaURLs) { RLMURLObject *urlObj = [[RLMURLObject alloc] init]; urlObj.urlString = url.absoluteString; // Store the URL as a string [realmURLObjects addObject:urlObj]; } // Assign to your media model MediaModel *mediaModel = [[MediaModel alloc] init]; // Set your other properties (image, audio, etc.) here mediaModel.mediaURLs = realmURLObjects; // Save to Realm RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm addObject:mediaModel]; [realm commitWriteTransaction];
When you fetch your model from Realm, convert the stored RLMURLObject instances back to NSURL:
// Fetch your saved model MediaModel *savedModel = [MediaModel allObjects].firstObject; // Convert back to NSURL array NSMutableArray<NSURL *> *retrievedURLs = [NSMutableArray array]; for (RLMURLObject *urlObj in savedModel.mediaURLs) { NSURL *url = [NSURL URLWithString:urlObj.urlString]; if (url) { // Add a check in case the string is invalid [retrievedURLs addObject:url]; } }
If you want to ensure only valid URLs are stored, you can add a validation method to RLMURLObject:
@implementation RLMURLObject + (BOOL)validateUrlString:(id)value error:(NSError **)error { if (![value isKindOfClass:[NSString class]] || ![NSURL URLWithString:value]) { if (error) { *error = [NSError errorWithDomain:@"RealmURLValidation" code:1 userInfo:@{NSLocalizedDescriptionKey: @"Invalid URL string"}]; } return NO; } return YES; } @end
That's it! This approach works because we're wrapping the non-supported NSURL type into a Realm-compatible object, and using RLMArray to handle the collection storage.
内容的提问来源于stack exchange,提问作者Nick

