I'm working on the same problem myself.
My current observation is, since NSUserDefaults standardDefault contain a hierarchy of objects (like a .plist) you can put all your SDK's default key/values inside some "Dictionary" entry, (e.g. named after your SDK's domain - "com.mydomain.frameworkname"). That will box your items and set them apart from the app's own values.
There is a downside here - that KVO will only work for top-level key/value changes, so you won't be able to "register" for default-value-changes done directly in the NSUserDefaults.
Then, there's the part of "first time" loading of "factory default values" for the SDK, into the NSUserDefaults standardDefaults. For that, there is a standard behaviour and API, called "registerDefaults".
You can have some .plist resource in your SDK's bundle, called "factoryDefaults.plist" and then, in the initialisation of your SDK, you'll do something like this:
NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"factoryDefaults" ofType:@"plist"];
NSDictionary* factorySettings = [NSDictionary dictionaryWithContentsOfFile:path];
[[NSUserDefaults standardDefaults] registerDefaults:factorySettings];
[[NSUserDefaults standardDefaults] synchronize];
Then you can continue working with your default values, using standard user-defaults APIs, you can update them as needed, and still keep your hosting app's defaults kind-of-clean.
It is possible to hide the nuisance of digging into your SDK's single entry in NSUserDefaults standardDefaults, in a class that will kind-of override NSUserDefaults functions, and will access the SDK's entry instead of the top-level standardDefaults.
Word of caution: I'm only doing this now - can't yet report of success. So I will be thankful for any critic and recommendations, and you're welcome to try this method.