Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve setItem performance on iOS #16

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions cpp/SecureStorageHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ void install(

const std::string key = arguments[0].getString(runtime).utf8(runtime);
const std::string value = arguments[1].getString(runtime).utf8(runtime);
const int accessible =
arguments[2].getNumber();
const int accessible = arguments[2].getNumber();
auto promise = runtime.global().getPropertyAsFunction(runtime, "Promise");
return promise.callAsConstructor(
runtime,
Expand Down Expand Up @@ -111,9 +110,9 @@ void install(
item.getProperty(runtime, "key").asString(runtime).utf8(runtime);
const auto value =
item.getProperty(runtime, "value").asString(runtime).utf8(runtime);
const auto accessibleValue = item.getProperty(runtime, "accessibleValue")
.getNumber();
itemsArray.push_back({key, value, static_cast<int>(accessibleValue)});
const auto accessibleValue =
item.getProperty(runtime, "accessibleValue").getNumber();
itemsArray.push_back({key, value, static_cast<int>(accessibleValue)});
}

auto promise = runtime.global().getPropertyAsFunction(runtime, "Promise");
Expand Down
6 changes: 4 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1237,13 +1237,15 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-fast-secure-storage (0.1.0):
- react-native-fast-secure-storage (1.1.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React
- React-callinvoker
- React-Core
- React-debug
- React-Fabric
Expand Down Expand Up @@ -1757,7 +1759,7 @@ SPEC CHECKSUMS:
React-logger: 4072f39df335ca443932e0ccece41fbeb5ca8404
React-Mapbuffer: 714f2fae68edcabfc332b754e9fbaa8cfc68fdd4
React-microtasksnativemodule: 4943ad8f99be8ccf5a63329fa7d269816609df9e
react-native-fast-secure-storage: b35a04cf343717cd50d57280d16d1fd9f4c6afc6
react-native-fast-secure-storage: b7c5601cab320f0de24f0f2d0becfe84df0ef81e
React-nativeconfig: 4a9543185905fe41014c06776bf126083795aed9
React-NativeModulesApple: 0506da59fc40d2e1e6e12a233db5e81c46face27
React-perflogger: 3bbb82f18e9ac29a1a6931568e99d6305ef4403b
Expand Down
71 changes: 29 additions & 42 deletions ios/SecureStorage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,35 @@
#import <Security/Security.h>

typedef NS_ENUM(NSInteger, AccessibilityLevel) {
AccessibleWhenUnlocked = 0,
AccessibleAfterFirstUnlock,
AccessibleAlways,
AccessibleWhenPasscodeSetThisDeviceOnly,
AccessibleWhenUnlockedThisDeviceOnly,
AccessibleAfterFirstUnlockThisDeviceOnly,
AccessibleAlwaysThisDeviceOnly
AccessibleWhenUnlocked = 0,
AccessibleAfterFirstUnlock,
AccessibleAlways,
AccessibleWhenPasscodeSetThisDeviceOnly,
AccessibleWhenUnlockedThisDeviceOnly,
AccessibleAfterFirstUnlockThisDeviceOnly,
AccessibleAlwaysThisDeviceOnly
};

CFStringRef _accessibleValue(const int accessible)
{
switch (accessible) {
case AccessibleWhenUnlocked:
return kSecAttrAccessibleWhenUnlocked;
case AccessibleAfterFirstUnlock:
return kSecAttrAccessibleAfterFirstUnlock;
case AccessibleAlways:
return kSecAttrAccessibleAlways;
case AccessibleWhenPasscodeSetThisDeviceOnly:
return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly;
case AccessibleWhenUnlockedThisDeviceOnly:
return kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
case AccessibleAfterFirstUnlockThisDeviceOnly:
return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
case AccessibleAlwaysThisDeviceOnly:
return kSecAttrAccessibleAlwaysThisDeviceOnly;
default:
return kSecAttrAccessibleWhenUnlocked; // Default case
}
case AccessibleWhenUnlocked:
return kSecAttrAccessibleWhenUnlocked;
case AccessibleAfterFirstUnlock:
return kSecAttrAccessibleAfterFirstUnlock;
case AccessibleAlways:
return kSecAttrAccessibleAlways;
case AccessibleWhenPasscodeSetThisDeviceOnly:
return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly;
case AccessibleWhenUnlockedThisDeviceOnly:
return kSecAttrAccessibleWhenUnlockedThisDeviceOnly;
case AccessibleAfterFirstUnlockThisDeviceOnly:
return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
case AccessibleAlwaysThisDeviceOnly:
return kSecAttrAccessibleAlwaysThisDeviceOnly;
default:
return kSecAttrAccessibleWhenUnlocked; // Default case
}
}

NSString *serviceName = nil;
Expand Down Expand Up @@ -190,33 +190,20 @@ bool secureStorageHasItem(const std::string key)
return status != errSecItemNotFound;
}

bool setSecureStorageItem(
const std::string key,
const std::string value,
const int accessible)
bool setSecureStorageItem(const std::string key, const std::string value, const int accessible)
{
NSMutableDictionary *dictionary = generateBaseQueryDictionary(key);

SecItemDelete((CFDictionaryRef)dictionary);

NSData *valueData = [NSData dataWithBytes:value.data() length:value.length()];
CFStringRef accessibleValue = _accessibleValue(accessible);
[dictionary setObject:valueData forKey:(id)kSecValueData];
dictionary[(__bridge NSString *)kSecAttrAccessible] = (__bridge id)accessibleValue;

OSStatus status = SecItemAdd((CFDictionaryRef)dictionary, NULL);

if (status == errSecSuccess) {
return true;
} else {
NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init];
[updateDictionary setObject:valueData forKey:(id)kSecValueData];
updateDictionary[(__bridge NSString *)kSecAttrAccessible] = (__bridge id)accessibleValue;
NSMutableDictionary *searchDictionary = generateBaseQueryDictionary(key);
OSStatus status =
SecItemUpdate((CFDictionaryRef)searchDictionary, (CFDictionaryRef)updateDictionary);

return status == errSecSuccess;
}

return true;
return status == errSecSuccess;
}

bool deleteSecureStorageItem(const std::string key)
Expand Down
Loading