What\'s is a reliable way to detect if user has enabled this API?
CGWindowListCreateImage returns a valid object even if screen recording API is disable
As of MacOS 10.15.7 the heuristics of obtaining window-names for visible windows, and so know we have screen-capture permission, doesn't always work. Sometimes we just don't find valid windows we can query, and would wrongly deduce we don't have permissions.
However, I found another way to directly query (using sqlite) the Apple TCC database - the model where permissions are persisted. The screen-recording permissions are to be found in the "System level" TCC database ( residing in /Library/Application Support/com.apple.TCC/TCC.db). If you open the database using sqlite, and query: SELECT allowed FROM access WHERE client="com.myCompany.myApp" AND service="kTCCServiceScreenCapture" you'll get your answer.
Two downsides comparing to other answers:
The up side -- it's a direct query of the actual thing, and does not rely on any windows, or processes to exist at the time of query.
Here's some draft code to do this:
NSString *client = @"com.myCompany.myApp";
sqlite3 *tccDb = NULL;
sqlite3_stmt *statement = NULL;
NSString *pathToSystemTCCDB = @"/Library/Application Support/com.apple.TCC/TCC.db";
const char *pathToDBFile = [pathToSystemTCCDB fileSystemRepresentation];
if (sqlite3_open(pathToDBFile, &tccDb) != SQLITE_OK)
return nil;
const char *query = [[NSString stringWithFormat: @"SELECT allowed FROM access WHERE client=\"%@\" AND service=\"kTCCServiceScreenCapture\"",client] UTF8String];
if (sqlite3_prepare_v2(tccDb, query , -1, &statement, nil) != SQLITE_OK)
return nil;
BOOL allowed = NO;
while (sqlite3_step(statement) == SQLITE_ROW)
allowed |= (sqlite3_column_int(statement, 0) == 1);
if (statement)
sqlite3_finalize(statement);
if (tccDb)
sqlite3_close(tccDb);
return @(allowed);
}