Reputation: 2572
I have an NSManagedObject
class that stores, among other things, a JSON string that comes from a WkWebView
form. The form in the web view allows the user to add images to the form; when the form is submitted, it is passed to the Cocoa layer via userContentController:didReceiveScriptMessage
as a JSON string. The images are included as Base64 encoded data URLs.
This works, but users add more images and larger images than anticipated, and it is rather uncool to store BLOBs in a database, IMHO. So I want to save the images into files in the app doc dir and patch the JSON string to refer to the images via file URL.
The sandbox directory (and thus the documents directory) changes on every app launch, so I cannot store absolute URLs in the database. Instead, I use a placeholder, [APP_DOC_DIR]
.
So basically the JSON data images have 3 states:
[APP_DOC_DIR]
placeholderTo make the changes at the appropriate locations and moments, I override the form data setter and getter of my NSManagedObject
instance.
#define FORM_DATA_KEY @"formData"
/// Form data setter
- (void) setFormData:(NSString *)form_data
{
// abbreviated heavily, just showing the concept
NSMutableString *data = form_data;
for (;;) {
// Find base64 data URL
// Save resulting NSData in a file
// Replace data URL with URL to the file, using [APP_DOC_DIR] placeholder
}
// Update the value Core Data sees
[self willChangeValueForKey:FORM_DATA_KEY];
[self setPrimitiveValue:data forKey:FORM_DATA_KEY];
[self didChangeValueForKey:FORM_DATA_KEY];
}
/// Form data getter
- (NSString*) formData
{
NSMutableString *data = [self primitiveValueForKey:FORM_DATA_KEY];
NSString *docsUrl = [NSURL fileURLWithPath:thisApp.docDir].absoluteString;
for (;;) {
// Replace all occurrences of [APP_DOC_DIR] with docsUrl
}
return data;
}
Basically, that's it. The replacement code is fast and works.
But the form data stored in the database contains absolute URLs. Apparently, not the value set in the setter with setPrimitiveValue
is being stored in the DB but the value returned from the getter.
What am I doing wrong?
Upvotes: 0
Views: 39
Reputation: 2572
Answering my own question...
I have not found why it failed overriding getter and setter. What finally solved it for me was to create dedicated getters and setters and leave the Core Data generated property with its getter and setter alone. I don't use it anymore at all, nowhere.
- (void) setFormDataWithBlobs:(NSString*) data
{
// Store BLOBs as files
// Replace BLOB base64 strings with file URLs using [APP_DOC_DIR] placeholder
// Then save the whole thing in Core Data:
[self willChangeValueForKey:FORM_DATA_KEY];
[self setPrimitiveValue:data forKey:FORM_DATA_KEY];
[self didChangeValueForKey:FORM_DATA_KEY];
}
- (NSString*) getPatchedFormData
{
// Get form data with placeholders from Core Data
NSString *s = [self primitiveValueForKey:FORM_DATA_KEY];
NSMutableString *data = [s mutableCopy];
// Replace [APP_DOC_DIR] with actual application docs dir
// ...
return data;
}
Upvotes: 0