I use the following:
[[NSWorkspace sharedWorkspace] openFile: /path/to/document withApplication: /path/to/app];
You can use "absolutePathForAppBundleWithIdentifier" to convert a bundle ID to an absolute path.
Note that the above works even from the sandbox and even when your document path is not sandbox-friendly. Also, /path/to/app is not Catalina-friendly. If you are running on Catalina and trying to open a system app, you must provide the "/System" prefix.
It looks like both of these methods are deprecated in 10.15. You should probably use "openURLs:withApplicationAtURL:configuration:completionHandler:" and "URLForApplicationWithBundleIdentifier:" for new apps that don't need compatibility with 10.14 or earlier.
Thanks for the elaborate answer John. That works.