Skip to content

Commit 1289267

Browse files
committed
feat: use asynccallback to handle async operations
1 parent 9121ecd commit 1289267

File tree

3 files changed

+35
-44
lines changed

3 files changed

+35
-44
lines changed

packages/apple-llm/ios/speech/AppleSpeech.mm

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#import <ReactCommon/RCTTurboModule.h>
1717

1818
#import <jsi/jsi.h>
19+
#import <react/bridging/Function.h>
1920

2021
#import <NativeAppleLLM/NativeAppleLLM.h>
2122

@@ -46,19 +47,15 @@ + (NSString *)moduleName {
4647
- (void)installGenerateFunc:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker {
4748
AppleSpeechImpl *speechModule = _speech;
4849

49-
auto runOnJS = [jsInvoker](std::function<void()>&& f) {
50-
jsInvoker->invokeAsync(std::move(f));
51-
};
52-
53-
jsInvoker->invokeAsync([speechModule, runOnJS](jsi::Runtime& rt) {
50+
jsInvoker->invokeAsync([speechModule, jsInvoker](jsi::Runtime& rt) {
5451
@try {
5552
auto global = rt.global();
5653

5754
auto generateAudioFunc = jsi::Function::createFromHostFunction(
5855
rt,
5956
jsi::PropNameID::forAscii(rt, "generateAudio"),
6057
2,
61-
[speechModule, runOnJS](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
58+
[speechModule, jsInvoker](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
6259
if (count < 1 || !args[0].isString()) {
6360
throw jsi::JSError(rt, "First argument must be a string (text)");
6461
}
@@ -93,12 +90,15 @@ - (void)installGenerateFunc:(std::shared_ptr<facebook::react::CallInvoker>)jsInv
9390
rt,
9491
jsi::PropNameID::forAscii(rt, "executor"),
9592
2,
96-
[speechModule, text, options, runOnJS](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
97-
auto resolve = std::make_shared<jsi::Function>(args[0].asObject(rt).asFunction(rt));
98-
auto reject = std::make_shared<jsi::Function>(args[1].asObject(rt).asFunction(rt));
93+
[speechModule, text, options, jsInvoker](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
94+
using ResolveCallback = facebook::react::AsyncCallback<NSData*>;
95+
using RejectCallback = facebook::react::AsyncCallback<NSString*, NSString*, NSError*>;
96+
97+
auto resolve = ResolveCallback(rt, args[0].asObject(rt).asFunction(rt), jsInvoker);
98+
auto reject = RejectCallback(rt, args[1].asObject(rt).asFunction(rt), jsInvoker);
9999

100100
[speechModule generateAudio:text options:options resolve:^(NSData *audioData) {
101-
runOnJS([resolve, audioData, &rt]() {
101+
resolve.call([audioData](jsi::Runtime& rt, jsi::Function& resolveFunc) {
102102
class NSDataMutableBuffer : public facebook::jsi::MutableBuffer {
103103
public:
104104
NSDataMutableBuffer(uint8_t* data, size_t size) : _data(data), _size(size) {}
@@ -115,12 +115,12 @@ - (void)installGenerateFunc:(std::shared_ptr<facebook::react::CallInvoker>)jsInv
115115
auto mutableBuffer = std::make_shared<NSDataMutableBuffer>(data, size);
116116
auto arrayBuffer = jsi::ArrayBuffer(rt, mutableBuffer);
117117

118-
resolve->call(rt, std::move(arrayBuffer));
118+
resolveFunc.call(rt, std::move(arrayBuffer));
119119
});
120120
} reject:^(NSString *code, NSString *message, NSError *error) {
121-
runOnJS([reject, message, &rt]() {
121+
reject.call([message](jsi::Runtime& rt, jsi::Function& rejectFunc) {
122122
auto jsError = jsi::String::createFromUtf8(rt, [message UTF8String]);
123-
reject->call(rt, jsError);
123+
rejectFunc.call(rt, jsError);
124124
});
125125
}];
126126

packages/apple-llm/ios/speech/AppleSpeechImpl.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,17 @@ public class AppleSpeechImpl: NSObject {
4242
}
4343

4444
var collectedBuffers: [AVAudioPCMBuffer] = []
45-
46-
var resolveCallback: ((Data) -> Void)? = resolve
47-
var rejectCallback: ((String, String, Error?) -> Void)? = reject
48-
45+
4946
speechSynthesizer.write(utterance) { buffer in
5047
guard let pcm = buffer as? AVAudioPCMBuffer else { return }
5148

5249
if pcm.frameLength == 0 {
53-
guard let resolve = resolveCallback, let reject = rejectCallback else { return }
54-
5550
do {
5651
let data = try AppleSpeechImpl.wavData(from: collectedBuffers)
5752
resolve(data)
5853
} catch {
5954
reject("AppleSpeech", "Error generating WAV data", error)
6055
}
61-
62-
resolveCallback = nil
63-
rejectCallback = nil
6456
return
6557
}
6658

packages/apple-llm/ios/transcription/AppleTranscription.mm

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#import <ReactCommon/RCTTurboModule.h>
1717

1818
#import <jsi/jsi.h>
19+
#import <react/bridging/Function.h>
1920

2021
#import <NativeAppleLLM/NativeAppleLLM.h>
2122

@@ -25,6 +26,7 @@ @interface AppleTranscription : NativeAppleTranscriptionSpecBase <NativeAppleTra
2526

2627
using namespace facebook;
2728
using namespace JS::NativeAppleLLM;
29+
using namespace react;
2830

2931
@implementation AppleTranscription
3032

@@ -45,19 +47,15 @@ + (NSString *)moduleName {
4547
- (void)installTranscribeFunc:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker {
4648
AppleTranscriptionImpl *transcriptionModule = _transcription;
4749

48-
auto runOnJS = [jsInvoker](std::function<void()>&& f) {
49-
jsInvoker->invokeAsync(std::move(f));
50-
};
51-
52-
jsInvoker->invokeAsync([transcriptionModule, runOnJS](jsi::Runtime& rt) {
50+
jsInvoker->invokeAsync([transcriptionModule, jsInvoker](jsi::Runtime& rt) {
5351
@try {
5452
auto global = rt.global();
5553

5654
auto transcribeFunc = jsi::Function::createFromHostFunction(
5755
rt,
5856
jsi::PropNameID::forAscii(rt, "transcribe"),
5957
2,
60-
[transcriptionModule, runOnJS](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
58+
[transcriptionModule, jsInvoker](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
6159
auto arrayBuffer = args[0].asObject(rt);
6260
if (!arrayBuffer.isArrayBuffer(rt)) {
6361
throw jsi::JSError(rt, "First argument must be an ArrayBuffer");
@@ -75,23 +73,24 @@ - (void)installTranscribeFunc:(std::shared_ptr<facebook::react::CallInvoker>)jsI
7573
rt,
7674
jsi::PropNameID::forAscii(rt, "executor"),
7775
2,
78-
[transcriptionModule, audioData, language, runOnJS](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
79-
auto resolve = std::make_shared<jsi::Function>(args[0].asObject(rt).asFunction(rt));
80-
auto reject = std::make_shared<jsi::Function>(args[1].asObject(rt).asFunction(rt));
76+
[transcriptionModule, audioData, language, jsInvoker](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) -> jsi::Value {
77+
using ResolveCallback = facebook::react::AsyncCallback<>;
78+
using RejectCallback = facebook::react::AsyncCallback<NSString*, NSString*, NSError*>;
79+
80+
auto resolve = ResolveCallback(rt, args[0].asObject(rt).asFunction(rt), jsInvoker);
81+
auto reject = RejectCallback(rt, args[1].asObject(rt).asFunction(rt), jsInvoker);
8182

82-
[transcriptionModule transcribe:audioData
83-
language:language
84-
resolve:^(id result) {
85-
runOnJS([resolve, result, &rt]() {
86-
auto jsResult = react::TurboModuleConvertUtils::convertObjCObjectToJSIValue(rt, result);
87-
resolve->call(rt, jsResult);
88-
});
89-
} reject:^(NSString *code, NSString *message, NSError *error) {
90-
runOnJS([reject, message, &rt]() {
91-
auto jsError = jsi::String::createFromUtf8(rt, [message UTF8String]);
92-
reject->call(rt, jsError);
93-
});
94-
}];
83+
[transcriptionModule transcribe:audioData language:language resolve:^(id result) {
84+
resolve.call([result](jsi::Runtime& rt, jsi::Function& resolveFunc) {
85+
auto jsResult = react::TurboModuleConvertUtils::convertObjCObjectToJSIValue(rt, result);
86+
resolveFunc.call(rt, jsResult);
87+
});
88+
} reject:^(NSString *code, NSString *message, NSError *error) {
89+
reject.call([message](jsi::Runtime& rt, jsi::Function& rejectFunc) {
90+
auto jsError = jsi::String::createFromUtf8(rt, [message UTF8String]);
91+
rejectFunc.call(rt, jsError);
92+
});
93+
}];
9594

9695
return jsi::Value::undefined();
9796
}

0 commit comments

Comments
 (0)