Integrating Appsalt SDK with macOS C/C++ applications
This guide shows how to integrate and use Appsalt 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 Appsalt 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 (appsalt.dmg) containing:
appsalt.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 appsalt.dmg in Finder, or run:
hdiutil attach appsalt.dmg
This mounts the image under /Volumes/Appsalt 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/Appsalt SDK/appsalt.framework" /Library/Frameworks/
Per-user:
mkdir -p ~/Library/Frameworks
cp -R "/Volumes/Appsalt SDK/appsalt.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 Appsalt 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 appsalt -o app
# C++
clang++ main.cpp -framework appsalt -o app
If the framework is not in a default path (e.g., per-user install):
clang++ main.cpp -F "$HOME/Library/Frameworks" -framework appsalt -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 appsalt -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 appsalt.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 appsalt.framework is two directories above samples/macos):
mkdir -p "$HOME/AppsaltSDK"
cp -a "/Volumes/Appsalt SDK/." "$HOME/AppsaltSDK/"
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 appsalt.framework is located two directories above samples/macos (i.e., samples/macos/../../appsalt.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/AppsaltSDK/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/AppsaltSDK/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 confirmappsalt.frameworkresolves from the expected path. -
Command Line Tools missing
Install with:xcode-select --install
Function reference
appsalt_start() and appsalt_stop() are non-blocking. Internally, starting and stopping the Appsalt SDK service are asynchronous operations, so there can be a slight delay before the action takes effect.
appsalt_init
Initialize the SDK service.
int32_t appsalt_init(const char *api_key);
Parameters
| Name | Type | Description |
|---|---|---|
api_key | const char* | Your API key provided by Appsalt SDK. |
Returns
0 on success; otherwise a negative error code.
Remarks
- If the service is already initialized and a different API key is provided, the old instance is terminated and a new one is initialized.
- If the service is already initialized and the same API key is provided, the function call effectively does nothing.
api_keyis copied by the SDK; its memory does not need to remain valid after the call returns.
It is required to call this function before any other SDK service function.
appsalt_start
Start the SDK service.
int32_t appsalt_start(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
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 function call effectively does nothing.
It is recommended to obtain user consent before starting the SDK service.
appsalt_stop
Stop the SDK service.
int32_t appsalt_stop(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Stops the SDK service if it is running.
- If the service is not running, this function does nothing.
It is recommended to stop the SDK service before closing your application so the service shuts down cleanly.
appsalt_identify
Get the SDK service identifier.
int32_t appsalt_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.
appsalt_is_running
Check if the SDK service is running.
int32_t appsalt_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.
appsalt_opt_in
Provide user consent.
int32_t appsalt_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
appsalt_start()will be allowed to start the service.
appsalt_opt_out
Revoke user consent.
int32_t appsalt_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
appsalt_start()will not be allowed to start the service.
appsalt_is_opted_in
Check whether user consent was given.
int32_t appsalt_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.
appsalt_request_consent
Display the default user agreement window and capture consent.
int32_t appsalt_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
appsalt_start()calls are allowed. - If the user declines or closes the window, subsequent
appsalt_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.
appsalt_log
Enable logging for the SDK service.
int32_t appsalt_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
appsalt_log()create a new log file in the specified directory.
appsalt_mute
Disable logging for the SDK service.
int32_t appsalt_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.