In case anyone else find this useful, here’s the code for setting/getting keychain entries that works on iOS: Setting:
const auto str_service = CFStringCreateWithCString( nullptr, service.toStdString().c_str(), kCFStringEncodingASCII );
const auto str_account = CFStringCreateWithCString( nullptr, account.toStdString().c_str(), kCFStringEncodingASCII );
const auto data = CFDataCreate( nullptr, (const UInt8 *)date.toStdString().c_str(), (CFIndex)date.length() );
CFMutableDictionaryRef query = CFDictionaryCreateMutable( nullptr, 0, nullptr, nullptr );
CFDictionaryAddValue( query, kSecClass, kSecClassGenericPassword );
CFDictionaryAddValue( query, kSecAttrService, str_service );
CFDictionaryAddValue( query, kSecAttrAccount, str_account );
CFDictionaryAddValue( query, kSecValueData, data );
const auto res = SecItemAdd( query, nullptr );
CFRelease( str_service );
CFRelease( str_account );
CFRelease( data );
and fetching:
const auto str_service = CFStringCreateWithCString( nullptr, service.toStdString().c_str(), kCFStringEncodingASCII );
const auto str_account = CFStringCreateWithCString( nullptr, account.toStdString().c_str(), kCFStringEncodingASCII );
CFMutableDictionaryRef query = CFDictionaryCreateMutable( nullptr, 0, nullptr, nullptr );
CFDictionaryAddValue( query, kSecClass, kSecClassGenericPassword );
CFDictionaryAddValue( query, kSecAttrService, str_service );
CFDictionaryAddValue( query, kSecAttrAccount, str_account );
CFDictionaryAddValue( query, kSecReturnData, kCFBooleanTrue );
CFDataRef ref = nullptr;
const auto res = SecItemCopyMatching( query, (CFTypeRef*)&ref );
CFRelease( str_service );
CFRelease( str_account );
if ( res == noErr && ref ) {
const auto len = CFDataGetLength( ref );
UInt8 data[ len ];
CFDataGetBytes( ref, CFRangeMake( (CFIndex)0, len ), data );
juce::String str( (char *)data, len );
return str;
}
return "";