I have filed two bug reports about the missing Documentation and APIs.
It is really frustrating to receive no official answer from Apple, you can not open a Code-Level Support ticket because it is beta Software and you don't get an answer here in the forum nor from the bug report either.
Our current backup assumption how to at least somewhat deterministic query the privacy setting would look something like this: (NOT TESTED DO NOT USE...)
import Darwin
import SQLite3
// Note: the TTCD does not like if another process reads from the DB directly. I noticed weird glitches when I ran this code.
// The list view in 'System Preferences > Security & Privacy > Privacy > Application Data' was shown empty
// although the table itself contained other entries.
func applicationDataAccess() -> Bool? {
let tccDBPath = "/Library/Application Support/com.apple.TCC/TCC.db"
let os = ProcessInfo().operatingSystemVersion
if os.majorVersion == 10 && os.minorVersion < 14 {
// There is no Privacy protection before Mojave
return true
}
// check if the TCC.db can be accessed or if it might be protected by the privacy protection
let fd = open(tccDBPath, O_RDONLY)
if fd < 0 {
if errno != EPERM {
// if an open is blocked by the new privacy protection errno is set to EPERM
// if errno is different we can not reliably say what's what
return nil
}
return false
}
close(fd)
var tccDB: OpaquePointer? = nil
guard sqlite3_open_v2(tccDBPath, &tccDB, SQLITE_OPEN_READONLY, nil) == SQLITE_OK else {
// the db can't be opened so what does that mean? --> nil
return nil
}
defer {
sqlite3_close(tccDB)
}
// if bundle doesn't contain an id fall back to path
let clientName = Bundle.main.bundleIdentifier ?? Bundle.main.bundlePath
let query = """
SELECT allowed
FROM access
WHERE service = "kTCCServiceSystemPolicyAllFiles"
AND client = "\(clientName)";
"""
var queryStatement: OpaquePointer? = nil
guard sqlite3_prepare_v2(tccDB, query, -1, &queryStatement, nil) == SQLITE_OK else {
return nil
}
if sqlite3_step(queryStatement) == SQLITE_ROW {
return sqlite3_column_int(queryStatement, 0) == 1
} else {
return false
}
}
Let's hope that we will receive propper API so that we don't have hacks like this! Plus this code won't work in a sandboxed application!