Read a bplist
A binary property list stores its objects in one region and an offset table at the end of the file. The last 32 bytes hold the trailer: the width of an offset, the width of a reference, how many objects exist, and which one is the root. Nothing can be read from the front of the file alone, which is why a plain hex dump of a .plist looks like unlabelled soup.
Load the file and the root object is expanded into JSON, following every reference as it goes.
Types the format carries
Integers come in 1, 2, 4, 8, and 16 byte widths, and only the 8-byte form is signed. Reals are 32 or 64 bit. Strings are stored as ASCII or UTF-16 big endian depending on their contents, so an emoji in a preference key changes how the whole string is written.
Dates are 8-byte doubles counting seconds since 2001-01-01. Data blobs stay hex. Sets exist alongside arrays and decode the same way.
NSKeyedArchiver files
An archive written by NSKeyedArchiver decodes into $version, $archiver, $top, and $objects. The values inside are UIDs rather than nested structures, and each one indexes the flat $objects array. Follow $top to its UID, look that index up in $objects, and repeat until the shape you expected appears.
This is normal for anything Apple serialized, including NSUserDefaults blobs and many app state files.