How to write defaults value from a file as bytes?

How to save content of a file into via defaults in such a way that they are handled as -data type?

In fact, I am searching for a command line alternative for this obj-c code:

NSData *data = // ... get the data
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:data forKey:@"mykey"];

When I call defaults read on that key I get:

% defaults read mydomain mykey
{length = 400, bytes = 0xdcf2dbbb cb4343d7 ec4324ae 1234de18 ... 289f4567 ec4324ae }

Later in an obj-c app, the data are read using:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [userDefaults dataForKey:@"mykey"];

Even I have no idea what the right approach to mimic setting the key is, I presume it might be something like:

% FILEDATA=... # read abc.xyz into a variable
% defaults write mydomain mykey -data "$FILEDATA" # save into user data

Solution 1:

Using the defaults command in Terminal, the following is a simple example of writing a key containing data as its value to a PLIST file:

% data='5468697320697320612064756D6D7920656E74727921'
% defaults write ~/Desktop/my.dummy.plist 'foobar' -data "$data"
% defaults read ~/Desktop/my.dummy.plist foobar           
{length = 22, bytes = 0x5468697320697320612064756d6d7920656e74727921}
% /usr/libexec/PlistBuddy -c 'print foobar' ~/Desktop/my.dummy.plist   
This is a dummy entry!
% 

To convert the contents of a file to hex data suitable for use with the defaults command, use the following:

% data="$(xxd -p '/path/to/file' | tr -d '\n')"

Or in place of "$data" in the example defaults command, replace it with:

"$(xxd -p '/path/to/file' | tr -d '\n')"

Example:

defaults write ~/Desktop/my.dummy.plist 'foobar' -data "$(xxd -p '/path/to/file' | tr -d '\n')"

Notes:

This syntax also works:

data='<5468697320697320612064756D6D7920656E74727921>'
defaults write ~/Desktop/my.dummy.plist 'foobar' "$data"

Note that < and > are used as part of data and the -data option was not used for the value type of the target key in the defaults command.

The hex data used in the example was created using the following command to convert the text string to hex data:

% xxd -p -u <<< 'This is a dummy entry!'
5468697320697320612064756D6D7920656E747279210A
% 

The use of the -u option with the xxd command is not absolutely necessary. I just like to see upper case hex data in the example.

After writing the data to a PLIST file in the first example further above, I use PlistBuddy to read the value of the target key. Keep in mind that in this simple example the value of foobar is just a text string and it outputs the converted hex data as shown, however, if the value of the data in the target key is e.g. a binary PLIST file itself or other binary data, the output isn't going to be pretty.