I’m pulling my hair out trying to implement what I assumed would be extremely basic: storing key-value pairs in the keychain in a Delphi iOS app. (In the Maui world it’s trivial using SecureStorage, butI’ve found no equivalent wrapper in Delphi. If anyone kknows any, please let me know!)
I’ve gone through the Apple docs, as well as whatever examples I could find online, but I’m stuck with an kSecParam error when storing.
Here’s some of the code I’ve tried so far:
function SaveToKeychain(const Key, Value: string) : Boolean;
var
query, attributes: NSMutableDictionary;
status: OSStatus;
keyData, valueData: NSData;
Data: CFDataRef;
valueBytes : TBytes;
testStr : String;
begin
Result := False;
try
query := TNSMutableDictionary.Create;
try
valueBytes := TEncoding.UTF8.GetBytes(Value);
//valueData := TNSData.Wrap(TNSData.alloc.initWithBytesNoCopy(@Value[1], Length(Value)));
//Data := CFDataCreate(nil, @Value[1], Length(Value) * SizeOf(Char));
try
// Define the keychain item attributes
query.setValue((kSecClassGenericPassword as ILocalObject).GetObjectID, kSecClass);
query.setValue((StrToNSStr(key) as ILocalObject).GetObjectID, kSecAttrAccount);
//query.setValue(Data, StrToNSStr('kSecValueData'));
query.setValue((StrToNSStr(Value) as ILocalObject).GetObjectID, StrToNSStr('kSecValueData'));
// Add the item to the keychain
status := SecItemAdd((query as ILocalObject).GetObjectID, nil);
finally
CFRelease(Data);
end;
AddToLog(Format('SaveToKeychain status: %d', [status]));
Result := (status = errSecSuccess);
finally
query.Release;
end;
except
on E:Exception do
AddToLog('Error in SaveToKeychain: ' + E.Message);
end;
end;
The SecItemAdd call returns a kSecParam error, which means one or more of the parameters/attributes is incorrect. I’ve assumed that it was the data, so I’ve tried several ways of adding it with no luck.
What am I missing??