Skip to content

Commit e17f0f8

Browse files
committed
ios integration
1 parent 94cc2e6 commit e17f0f8

File tree

16 files changed

+199
-148
lines changed

16 files changed

+199
-148
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ plugins {
1111
alias(libs.plugins.ksp) apply false
1212
alias(libs.plugins.androidx.room) apply false
1313
alias(libs.plugins.mavenPublish) apply false
14+
alias(libs.plugins.skie) apply false
1415
}

examples/example-react-native/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,7 @@ EXTERNAL SOURCES:
19451945
:path: "../node_modules/react-native/ReactCommon/yoga"
19461946

19471947
SPEC CHECKSUMS:
1948-
AsyncStorage: 44cab948e78a4444e02c50f4f44f336a1424e0a1
1948+
AsyncStorage: e48f2e48ebaf834ae6f82fe5198a172bfe888505
19491949
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
19501950
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
19511951
fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6

gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ room = "2.8.0"
1414
sqlite = "2.6.0"
1515
ksp = "2.2.10-2.0.2" # must match kotlin
1616
publish = "0.34.0"
17+
skie = "0.10.6"
1718

1819
[libraries]
1920
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
@@ -41,4 +42,5 @@ kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref =
4142
androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
4243
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
4344
androidx-room = { id = "androidx.room", version.ref = "room" }
44-
mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "publish" }
45+
mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "publish" }
46+
skie = { id = "co.touchlab.skie", version.ref = "skie" }

packages/async-storage/AsyncStorage.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
1717
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
1818
s.private_header_files = "ios/**/*.h"
1919
s.swift_version = "5.9.2"
20-
s.vendored_frameworks = "ios/Frameworks/SharedStorage.xcframework"
20+
s.vendored_frameworks = "ios/Frameworks/SharedAsyncStorage.xcframework"
2121

2222

2323
install_modules_dependencies(s)

packages/async-storage/ios/AsyncStorage.mm

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,39 @@
11
#import "AsyncStorage.h"
22
#import "AsyncStorage-Swift.h"
33

4-
@interface AsyncStorage()
5-
@property (nonatomic, strong) PersistentStorage *mod;
6-
@end
7-
84
@implementation AsyncStorage
95
RCT_EXPORT_MODULE(RNAsyncStorage)
106

11-
- (instancetype)init
12-
{
13-
self = [super init];
14-
if (self) {
15-
self.mod = [PersistentStorage new];
16-
}
17-
return self;
18-
}
19-
20-
- (void)getValues:(nonnull NSString *)db keys:(nonnull NSArray *)keys resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
21-
[self.mod getWithKeys:keys dbName:db resolver:resolve rejecter:reject];
7+
- (void)getValues:(nonnull NSString *)dbName keys:(nonnull NSArray *)keys resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
8+
9+
PersistentStorage* db = [StorageRegistry.shared getOrCreateWithDbName:dbName];
10+
[db getWithKeys:keys resolver:resolve rejecter:reject];
2211
}
2312

24-
// JS sends {key: string, value: string}[] type
25-
- (void)setValues:(nonnull NSString *)db values:(nonnull NSArray<NSDictionary *> *)values resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
13+
- (void)setValues:(nonnull NSString *)dbName values:(nonnull NSArray<NSDictionary *> *)values resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
2614

27-
[self.mod setWithEntries:values dbName:db resolver:resolve rejecter:reject];
15+
PersistentStorage* db = [StorageRegistry.shared getOrCreateWithDbName:dbName];
16+
[db setWithValues:values resolver:resolve rejecter:reject];
2817
}
2918

3019

31-
- (void)removeValues:(nonnull NSString *)db keys:(nonnull NSArray *)keys resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
32-
[self.mod removeWithKeys:keys dbName:db resolver:resolve rejecter:reject];
20+
- (void)removeValues:(nonnull NSString *)dbName keys:(nonnull NSArray *)keys resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
21+
22+
PersistentStorage* db = [StorageRegistry.shared getOrCreateWithDbName:dbName];
23+
[db removeWithKeys:keys resolver:resolve rejecter:reject];
3324
}
3425

3526

36-
- (void)clearStorage:(nonnull NSString *)db resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
37-
[self.mod clearWithDbName:db resolver:resolve rejecter:reject];
27+
- (void)clearStorage:(nonnull NSString *)dbName resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
28+
29+
PersistentStorage* db = [StorageRegistry.shared getOrCreateWithDbName:dbName];
30+
[db clearWithResolver:resolve rejecter:reject];
3831
}
3932

40-
- (void)getKeys:(nonnull NSString *)db resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
41-
[self.mod allKeysWithDbName:db resolver:resolve rejecter:reject];
33+
- (void)getKeys:(nonnull NSString *)dbName resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
34+
35+
PersistentStorage* db = [StorageRegistry.shared getOrCreateWithDbName:dbName];
36+
[db allKeysWithResolver:resolve rejecter:reject];
4237
}
4338

4439

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,88 @@
11
import React
2+
import SharedAsyncStorage
23

4+
/**
5+
TODO:
6+
- handle exceptions
7+
*/
38
@objc
4-
public class PersistentStorage: NSObject
5-
{
9+
public class PersistentStorage: NSObject {
10+
private let db: SharedStorage
11+
12+
init(databaseName: String) {
13+
db = SharedStorage.companion.create(context: PlatformContext.Instance(), databaseName: databaseName)
14+
}
15+
616
@objc
717
public func get(
818
keys: [String],
9-
dbName: String,
1019
resolver: @escaping RCTPromiseResolveBlock,
11-
rejecter: @escaping RCTPromiseRejectBlock
12-
)
13-
{
14-
// TODO: call db, get results, call resolve/reject
15-
_ = StorageRegistry.shared.getOrCreate(dbName: dbName)
16-
rejecter("ERR_01", "get not implemented", nil)
17-
20+
rejecter _: @escaping RCTPromiseRejectBlock
21+
) {
22+
Task {
23+
let result = try await self.db.getValues(keys: keys)
24+
resolver(result.map { $0.toRNValue() })
25+
}
1826
}
1927

2028
@objc
2129
public func set(
22-
entries: [[String: String]],
23-
dbName: String,
30+
values: [[String: String]],
2431
resolver: @escaping RCTPromiseResolveBlock,
25-
rejecter: @escaping RCTPromiseRejectBlock
26-
)
27-
{
28-
// TODO: call db, save results, call resolve/reject
29-
_ = StorageRegistry.shared.getOrCreate(dbName: dbName)
30-
rejecter("ERR_01", "set not implemented", nil)
32+
rejecter _: @escaping RCTPromiseRejectBlock
33+
) {
34+
Task {
35+
let entries = values.map { entry in Entry.fromRNValue(rnValue: entry) }
36+
let result = try await self.db.setValues(entries: entries)
37+
resolver(result.map { entry in entry.toRNValue() })
38+
}
3139
}
3240

3341
@objc
3442
public func remove(
3543
keys: [String],
36-
dbName: String,
3744
resolver: @escaping RCTPromiseResolveBlock,
38-
rejecter: @escaping RCTPromiseRejectBlock
39-
)
40-
{
41-
// TODO: call db, remove entries, call resolve/reject
42-
_ = StorageRegistry.shared.getOrCreate(dbName: dbName)
43-
rejecter("ERR_01", "remove not implemented", nil)
45+
rejecter _: @escaping RCTPromiseRejectBlock
46+
) {
47+
Task {
48+
try await self.db.removeValues(keys: keys)
49+
resolver(nil)
50+
}
4451
}
4552

4653
@objc
47-
public func clear(
48-
dbName: String,
54+
public func allKeys(
4955
resolver: @escaping RCTPromiseResolveBlock,
50-
rejecter: @escaping RCTPromiseRejectBlock
51-
)
52-
{
53-
// TODO: get db, clear, call resolve/reject
54-
_ = StorageRegistry.shared.getOrCreate(dbName: dbName)
55-
rejecter("ERR_01", "clear not implemented", nil)
56+
rejecter _: @escaping RCTPromiseRejectBlock
57+
) {
58+
Task {
59+
let keys = try await self.db.getKeys()
60+
resolver(keys)
61+
}
5662
}
5763

5864
@objc
59-
public func allKeys(
60-
dbName: String,
65+
public func clear(
6166
resolver: @escaping RCTPromiseResolveBlock,
62-
rejecter: @escaping RCTPromiseRejectBlock
63-
)
64-
{
65-
// TODO: get db, read keys, call resolve/reject
66-
_ = StorageRegistry.shared.getOrCreate(dbName: dbName)
67-
rejecter("ERR_01", "allKeys not implemented", nil)
67+
rejecter _: @escaping RCTPromiseRejectBlock
68+
) {
69+
Task {
70+
try await self.db.clear()
71+
resolver(nil)
72+
}
73+
}
74+
}
75+
76+
extension Entry {
77+
// js expects: {key: string, value: string?}
78+
func toRNValue() -> [String: String?] {
79+
["key": key, "value": value]
80+
}
81+
82+
static func fromRNValue(rnValue: [String: String]) -> Entry {
83+
let key: String = rnValue["key"]! // will throw in not there
84+
let value = rnValue["value"]
85+
86+
return Entry(key: key, value: value)
6887
}
6988
}
Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
/**
2-
* A registry for managing multiple AsyncStorage database instances.
3-
* Provides a shared singleton to get instance of AsyncStorage by name.
4-
*/
5-
class StorageRegistry {
6-
private init() {}
7-
8-
static let shared = StorageRegistry()
9-
10-
private var databases: [String: Storage] = [:]
11-
12-
func getOrCreate(dbName: String) -> Storage {
1+
@objc
2+
public class StorageRegistry: NSObject {
3+
override private init() {
4+
super.init()
5+
}
6+
7+
@objc
8+
public static let shared = StorageRegistry()
9+
10+
private var databases: [String: PersistentStorage] = [:]
11+
12+
@objc
13+
public func getOrCreate(dbName: String) -> PersistentStorage {
1314
if let storage = databases[dbName] {
1415
return storage
1516
}
16-
17-
// TODO: db create
18-
databases[dbName] = dbName
19-
return dbName
17+
18+
let db = PersistentStorage(databaseName: dbName)
19+
databases[dbName] = db
20+
return db
2021
}
2122
}
22-
23-
// TODO: Storage impl
24-
typealias Storage = String

packages/async-storage/src/native-module/NativeAsyncStorage.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import { TurboModuleRegistry } from "react-native";
33

44
export interface Spec extends TurboModule {
55
getValues: (
6-
db: string,
6+
dbName: string,
77
keys: string[]
88
) => Promise<{ key: string; value: string | null }[]>;
99

1010
setValues: (
11-
db: string,
11+
dbName: string,
1212
values: { key: string; value: string | null }[]
1313
) => Promise<{ key: string; value: string | null }[]>;
1414

15-
removeValues: (db: string, keys: string[]) => Promise<void>;
15+
removeValues: (dbName: string, keys: string[]) => Promise<void>;
1616

17-
getKeys: (db: string) => Promise<string[]>;
17+
getKeys: (dbName: string) => Promise<string[]>;
1818

19-
clearStorage: (db: string) => Promise<void>;
19+
clearStorage: (dbName: string) => Promise<void>;
2020
}
2121

2222
export default TurboModuleRegistry.get<Spec>("RNAsyncStorage");

scripts/build-native-lib.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ ANDROID_OUTPUT_DIR="$MODULE_NAME/build"
1010
ANDROID_RN_OUTPUT_DIR="$RN_MODULE_DIR/android"
1111
ANDROID_PUBLISH_TASK="publishAndroidPublicationToLocalRepoRepository"
1212

13-
IOS_BUILD_TASK="assembleSharedStorageXCFramework"
14-
IOS_OUTPUT_NAME="SharedStorage.xcframework"
13+
IOS_BUILD_TASK="assembleSharedAsyncStorageXCFramework"
14+
IOS_OUTPUT_NAME="SharedAsyncStorage.xcframework"
1515
IOS_OUTPUT_DIR="$MODULE_NAME/build/XCFrameworks/release"
1616
IOS_RN_OUTPUT_DIR="$RN_MODULE_DIR/ios/Frameworks"
1717

shared-storage/build.gradle.kts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ plugins {
77
alias(libs.plugins.ksp)
88
alias(libs.plugins.androidx.room)
99
alias(libs.plugins.mavenPublish)
10+
alias(libs.plugins.skie)
1011
}
1112

1213
kotlin {
@@ -30,12 +31,13 @@ kotlin {
3031
withDeviceTest {}
3132
}
3233

33-
val xcfName = "SharedStorage"
34+
val xcfName = "SharedAsyncStorage"
3435
val xcf = XCFramework(xcfName)
3536
listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach {
3637
it.binaries.framework {
3738
baseName = xcfName
3839
xcf.add(this)
40+
binaryOption("bundleId", "org.asyncstorage.shared_storage")
3941
}
4042
}
4143

@@ -83,6 +85,12 @@ kotlin {
8385
}
8486
}
8587

88+
skie {
89+
build {
90+
produceDistributableFramework()
91+
}
92+
}
93+
8694
publishing {
8795
repositories {
8896
maven {

0 commit comments

Comments
 (0)