2

我用谷歌搜索了这个问题,但找不到任何有用的东西,如何通过 Delphi XE6 将数据存储在 ios 设备 KeyChain 中?

4

1 回答 1

2

你可以这样做:

    aGetQueryDict := TNSMutableDictionary.Create;
    try

      aKeyStr := StrToNSStr('com.sample.mykey');
      aGetQueryDict.setValue((kSecClassGenericPassword as ILocalObject).GetObjectID, kSecClass);
      aGetQueryDict.setValue((aKeyStr as ILocalObject).GetObjectID, kSecAttrAccount);
      aGetQueryDict.setValue(kCFBooleanTrue, kSecReturnData);
      aGetQueryDict.setValue((kSecMatchLimitOne as ILocalObject).GetObjectID, kSecMatchLimit);

      aValuePointer := nil;
      aStatus := SecItemCopyMatching((aGetQueryDict as ILocalObject).GetObjectID, @aValuePointer);
      if (aStatus <> errSecSuccess) then begin

        aValueStr := 'MyValue';
        aValueBytes := Tencoding.UTF8.GetBytes(aValueStr);
        aValueData := TNSData.Wrap(TNSData.alloc.initWithBytesNoCopy(@aValueBytes[0], length(aValueBytes)));
        try
          aAddQueryDict := TNSMutableDictionary.Create;
          try

            aAddQueryDict.setValue((kSecClassGenericPassword as ILocalObject).GetObjectID, kSecClass);
            aAddQueryDict.setValue((aKeyStr as ILocalObject).GetObjectID, kSecAttrAccount);
            aAddQueryDict.setValue((aValueData as ILocalObject).GetObjectID, kSecValueData);

            aStatus := SecItemAdd((aAddQueryDict as ILocalObject).GetObjectID, NiL);
            if (aStatus <> errSecSuccess) then begin

            end;
          finally
            aAddQueryDict.release;
          end;
        finally
          //aValueData.release; >> i have an exception if i do this !
        end;

      end
      else begin
        aValueData := TNSData.Wrap(aValuePointer);
        SetLength(aValueBytes, aValueData.length);
        aValueData.getBytes(@aValueBytes[0], aValueData.length);
        AValueStr := Tencoding.UTF8.GetString(aValueBytes);
      end;
    finally
      aGetQueryDict.release;
    end;
于 2018-04-03T18:11:53.583 回答