You should also consider checking out Piercing the String Veil to help provide further clarity on the various String representations. Note that the above reference to "contiguous UTF-8" is important: a String will be opaque if it is incapable of providing a pointer to contiguous UTF-8 bytes. It doesn't matter which of those two constraints it can't satisfy: it may store contiguous UTF-16 bytes, or it may store discontiguous UTF-8, either will force the String type to be opaque.
The way I think of what “contiguous” means in this context is less that it is contiguous, and more that it provides access to its contiguousness. So a random NSString may or may not be contiguous in practice, but if we can’t ask it (via CFStringGetCString or its private ObjC counterpart) for that storage, then it may as well not be for our purposes.