Skip to main content

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.

info

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 a Makefile and macos.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
note

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​

  1. Add appsalt.framework to your target (File → Add Files… or drag into the project).
  2. For an application bundle, set Embed & Sign in General → Frameworks, Libraries, and Embedded Content (places it in Contents/Frameworks and configures runtime search paths).
    For command-line tools, Do Not Embed is typically sufficient.
  3. 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.

note

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.

Using clang++​

clang++ -O2 -Wall -pthread -F../.. -framework appsalt -rpath @executable_path/../.. -o app main.cpp
./app

Xcode​

  1. Open the project: open "$HOME/AppsaltSDK/samples/macos/macos.xcodeproj"
  2. Select the macos scheme.
  3. 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/../Frameworks as 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?
    Run otool -L ./app to list linked frameworks and confirm appsalt.framework resolves from the expected path.

  • Command Line Tools missing
    Install with:

    xcode-select --install

Function reference​

note

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​

NameTypeDescription
api_keyconst 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_key is copied by the SDK; its memory does not need to remain valid after the call returns.
note

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​

NameTypeDescription
stateint32_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 *state is set to 0.
  • If the service is already running, the function call effectively does nothing.
note

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.
note

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​

NameTypeDescription
datachar*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.
sizesize_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 == NULL to get required size (in bytes), allocate that many bytes, then call again with data and size.
  • 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), *size is set to the number of bytes actually written, and the function returns 0.

appsalt_is_running​

Check if the SDK service is running.

int32_t appsalt_is_running(int32_t *state);

Parameters​

NameTypeDescription
stateint32_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​

NameTypeDescription
stateint32_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.

Display the default user agreement window and capture consent.

int32_t appsalt_request_consent(int32_t *state);

Parameters​

NameTypeDescription
stateint32_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.
note

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​

NameTypeDescription
dirconst 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.