Integrating the Honeygain SDK with macOS C/C++ applications
This guide shows how to integrate and use the Honeygain SDK in macOS C/C++ applications. It can also be used from any technology that supports the C ABI on macOS.
Don't forget to generate your Honeygain SDK API Key and download the SDK from the Developers dashboard first.
Supported platforms: Apple Silicon (arm64) on macOS 11.0+, and Intel (x86_64) on macOS 10.12+.
On macOS, the SDK is distributed as a disk image (hgsdk.dmg) containing:
hgsdk.framework— the framework bundle.samples/macos/— a sample application with aMakefileandmacos.xcodeproj. Both methods write build output into the same directory (samples/macos/).
Mount the disk image
Double-click hgsdk.dmg in Finder, or run:
hdiutil attach hgsdk.dmg
This mounts the image under /Volumes/Honeygain SDK/.
You can build the sample directly from the mounted image for a quick start, or copy the framework and sample directory elsewhere.
Install the framework
Install the framework so the compiler/linker can find it automatically, and so your applications can locate it at runtime without fragile custom search paths.
System-wide (admin):
sudo cp -R "/Volumes/Honeygain SDK/hgsdk.framework" /Library/Frameworks/
Per-user:
mkdir -p ~/Library/Frameworks
cp -R "/Volumes/Honeygain SDK/hgsdk.framework" ~/Library/Frameworks/
macOS toolchains search /Library/Frameworks and /System/Library/Frameworks by default. If you install the framework to ~/Library/Frameworks or any custom location, pass -F <path> (or configure Framework Search Paths in Xcode).
Building with the SDK
The Honeygain SDK can be integrated with applications built from the command line as well as with projects managed with Xcode and other IDEs/build systems like CLion, Make, or Ninja.
Command line
Minimal commands when the framework is in a default path (e.g., /Library/Frameworks):
# C
clang main.c -framework hgsdk -o app
# C++
clang++ main.cpp -framework hgsdk -o app
If the framework is not in a default path (e.g., per-user install):
clang++ main.cpp -F "$HOME/Library/Frameworks" -framework hgsdk -o app
If you produce a GUI .app bundle and embed the framework in Contents/Frameworks, add an rpath so the loader can find it at runtime:
clang++ main.cpp -framework hgsdk -rpath @executable_path/../Frameworks -o app
Rpath tip: for helper tools, plug-ins, or other secondary binaries where the loader base is not the main application executable, prefer @loader_path/../Frameworks instead of @executable_path/../Frameworks.
Xcode
- Add hgsdk.framework to your target (File → Add Files… or drag into the project).
- For an application bundle, set Embed & Sign in General → Frameworks, Libraries, and Embedded Content (places it in
Contents/Frameworksand configures runtime search paths).
For command-line tools, Do Not Embed is typically sufficient. - If the framework is under a non-default path (e.g.,
~/Library/Frameworks), add that directory to Framework Search Paths (FRAMEWORK_SEARCH_PATHS).
Signing note: when Embed & Sign is enabled, Xcode signs the embedded framework automatically; for distribution, ensure the application and embedded framework are signed and notarized.
Running the sample application
Before building, copy the SDK contents from the mounted image to a writable location (the commands below keep the sample’s expected layout where hgsdk.framework is two directories above samples/macos):
mkdir -p "$HOME/HoneygainSDK"
cp -a "/Volumes/Honeygain SDK/." "$HOME/HoneygainSDK/"
Build and run the sample application via either the command line or Xcode. Both approaches use the same source; choose the one that fits your workflow.
The sample assumes hgsdk.framework is located two directories above samples/macos (i.e., samples/macos/../../hgsdk.framework). The copy commands above maintain this layout. If you move either the framework or the sample, update the -F path (manual/Make) or the Framework Search Paths (Xcode project) accordingly.
Command line
Change into the sample directory:
cd "$HOME/HoneygainSDK/samples/macos"
Command-line builds: choose one of the following methods. All produce output in the current directory.
- Manual
- Make
- xcodebuild
Xcode
- Open the project:
open "$HOME/HoneygainSDK/samples/macos/macos.xcodeproj" - Select the macos scheme.
- Press ⌘R to build and run.
Xcode supports development, debugging, embedding the framework into an application bundle, and signing.
Common Pitfalls
-
Framework not found at runtime
Use@executable_path/../Frameworksas an rpath for application bundles (or embed the framework via Xcode’s Embed & Sign). For helper tools, prefer@loader_path/../Frameworks. -
Non-default install path not on the build search path
If you installed to~/Library/Frameworks(or elsewhere), add-F "$HOME/Library/Frameworks"to your command line or set Framework Search Paths in Xcode. -
Unsure which framework your binary links to?
Runotool -L ./appto list linked frameworks and confirmhgsdk.frameworkresolves from the expected path. -
Command Line Tools missing
Install with:xcode-select --install
Function reference
hgsdk_start() and hgsdk_stop() are non-blocking. Internally, starting and stopping the Honeygain SDK service are asynchronous operations, so there can be a slight delay before the action takes effect.
hgsdk_start
Start the SDK service.
int32_t hgsdk_start(const char *api_key, int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
api_key | const char* | Your API key provided by Honeygain SDK. |
state | int32_t* | Out: consent state. Set to 1 if user consent was previously given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Checks whether explicit user consent was given before. The current consent state is returned via
*state. - If consent was previously given, the SDK service starts. If not, the service does not start and
*stateis set to0. - If the service is already running, the old instance is stopped and a new one is started with the provided API key.
api_keyis copied by the SDK; its memory does not need to remain valid after the call returns.
It is recommended to obtain user consent before starting the SDK service.
hgsdk_stop
Stop the SDK service.
int32_t hgsdk_stop(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Stops the SDK service if it is running and releases all resources.
- If the service is not running, this function does nothing.
It is recommended to stop the SDK service before closing your application to ensure all resources are released properly.
hgsdk_is_running
Check if the SDK service is running.
int32_t hgsdk_is_running(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the service is running, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
hgsdk_opt_in
Provide user consent.
int32_t hgsdk_opt_in(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was given and informs the SDK service that it may start.
- Subsequent calls to
hgsdk_start()will be allowed to start the service.
hgsdk_opt_out
Revoke user consent.
int32_t hgsdk_opt_out(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was revoked and informs the SDK service that it should stop if running.
- Subsequent calls to
hgsdk_start()will not be allowed to start the service.
hgsdk_is_opted_in
Check whether user consent was given.
int32_t hgsdk_is_opted_in(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if consent was given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Returns the stored consent state via
*state.
hgsdk_request_consent
Display the default user agreement window and capture consent.
int32_t hgsdk_request_consent(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the user accepts, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Shows the default user agreement UI.
- If the user accepts, consent is stored and the SDK service may start. Subsequent
hgsdk_start()calls are allowed. - If the user declines or closes the window, subsequent
hgsdk_start()calls are not allowed unless consent was previously given.
This function is blocking and returns only after the user accepts or declines the agreement.
hgsdk_identify
Get the SDK service identifier.
int32_t hgsdk_identify(char *data, size_t *size);
Parameters
| Name | Type | Description |
|---|---|---|
data | char* | Buffer to receive a NUL-terminated ASCII string. If not NULL, the function writes up to *size bytes and sets *size to the number of bytes actually written. |
size | size_t* | In/out. If data is NULL, on return *size is set to the number of bytes required to store the full NUL-terminated string. If data is not NULL, on return *size is set to the number of bytes actually written. |
Returns
0 on success; otherwise a negative error code.
Remarks
- The identifier is stable across runs on the device.
- Use the two-call pattern to retrieve the full value: call with
data == NULLto get required size (in bytes), allocate that many bytes, then call again withdataandsize. - The returned string is NUL-terminated and plain ASCII.
- If the provided buffer (
data/*size) is smaller than required, the string is truncated to fit (ensuring NUL termination when*size > 0),*sizeis set to the number of bytes actually written, and the function returns0.
hgsdk_log
Enable logging for the SDK service.
int32_t hgsdk_log(const char *dir);
Parameters
| Name | Type | Description |
|---|---|---|
dir | const char* | Directory where log files will be stored. If NULL or empty, logs are created in the current working directory. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Enables logging and writes logs to the specified directory (created if it does not exist).
- Logs are also written to standard output.
- Subsequent calls to
hgsdk_log()create a new log file in the specified directory.
hgsdk_mute
Disable logging for the SDK service.
int32_t hgsdk_mute(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Disables logging: closes any open log file and stops writing to standard output.
- Existing log files are not deleted and can be inspected for debugging.