TILicenseCheck

Two functions, one answer. Use whichever suits your build.

Signatures
// Compiled into your tweak from the header.
bool TILicenseCheck_inline(const char *packageID);

// Called from TI_Support.dylib.
bool TILicenseCheck(const char *packageID);

Which to use

TILicenseCheck_inlineTILicenseCheck
Lives inyour tweakTI_Support.dylib
Leaves a licensing symbol behindnoyes
Caches the answernoyes, per package
Works without TI_Support installedyesno

If you are only calling it once, take the inline one. If you are calling it often and want the caching, take the dylib one. The macros use both together, which is harder to defeat than either alone.

Parameters

packageID is your reverse-DNS identifier, exactly as it appears in the control file.

Returns

true when a receipt exists for that identifier, its signature verifies, it was issued for this Mac, and it has not expired. false otherwise, including when the file is missing or unreadable. It always fails closed.

Cheap to call repeatedly: this Mac's identity is worked out once and remembered for the life of the process.

Example

Objective-C
#import "TILicense.h"

__attribute__((constructor))
static void init(void) {
    if (!TILicenseCheck_inline("com.example.mytweak")) return;
    install_my_hooks();
}

See also

This is the readable form, and the easiest to patch out. Dispatch Macros and Pointer Guards spread the same decision through your code, and Licensing explains when that is worth doing.