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:
- Base64 data URLs as created by JS code in WkWebView
- File URLs with
[APP_DOC_DIR]
placeholder - File URLs with correct absolute path when displaying the data in WkWebView
To 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?