Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3406285
D7973.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D7973.diff
View Options
diff --git a/native/expo-modules/comm-expo-package/expo-module.config.json b/native/expo-modules/comm-expo-package/expo-module.config.json
--- a/native/expo-modules/comm-expo-package/expo-module.config.json
+++ b/native/expo-modules/comm-expo-package/expo-module.config.json
@@ -1,7 +1,7 @@
{
"platforms": ["ios", "android"],
"ios": {
- "modules": ["AESCryptoModule", "ThumbhashModule"]
+ "modules": ["AESCryptoModule", "BlobUtilsModule", "ThumbhashModule"]
},
"android": {
"modules": [
diff --git a/native/expo-modules/comm-expo-package/ios/AESCryptoModule.swift b/native/expo-modules/comm-expo-package/ios/AESCryptoModule.swift
--- a/native/expo-modules/comm-expo-package/ios/AESCryptoModule.swift
+++ b/native/expo-modules/comm-expo-package/ios/AESCryptoModule.swift
@@ -66,19 +66,6 @@
plaintext.copyBytes(to: destination.rawBufferPtr())
}
-// MARK: - Utilities
-
-extension TypedArray {
- func data() -> Data {
- Data(bytes: self.rawPointer, count: self.byteLength)
- }
-
- func rawBufferPtr() -> UnsafeMutableRawBufferPointer {
- UnsafeMutableRawBufferPointer(start: self.rawPointer,
- count: self.byteLength)
- }
-}
-
// MARK: - Exception definitions
private class InvalidKeyLengthException: Exception {
diff --git a/native/expo-modules/comm-expo-package/ios/BlobUtilsModule.swift b/native/expo-modules/comm-expo-package/ios/BlobUtilsModule.swift
new file mode 100644
--- /dev/null
+++ b/native/expo-modules/comm-expo-package/ios/BlobUtilsModule.swift
@@ -0,0 +1,70 @@
+import ExpoModulesCore
+
+// This type corresponds to the BlobData interface in react-native
+struct BlobMetadata: Record {
+ @Field var blobId: String
+ @Field var size: Int
+ @Field var offset: Int
+}
+
+public class BlobUtilsModule: Module {
+ public func definition() -> ModuleDefinition {
+ Name("BlobUtils")
+
+ Function("copyBlobToTypedArray") {
+ (blob: BlobMetadata, destination: Uint8Array) throws in
+ let blobManager = try self.getReactBlobManager()
+ guard let blobData = blobManager.resolve(blob.blobId,
+ offset: blob.offset,
+ size: blob.size) else {
+ throw NoSuchBlobException(blob.blobId)
+ }
+ blobData.copyBytes(to: destination.rawBufferPtr())
+ }
+
+ Function("blobFromTypedArray") { (source: TypedArray) throws -> String in
+ let blobManager = try self.getReactBlobManager()
+ guard let blobID = blobManager.store(source.data()) else {
+ throw BlobCreationFailedException()
+ }
+ return blobID
+ }
+ }
+
+ private func getReactBlobManager() throws -> RCTBlobManager {
+ guard let bridge = self.appContext?.reactBridge else {
+ throw BridgeNotFoundException()
+ }
+ guard let blobManager = bridge.module(for: RCTBlobManager.self)
+ as? RCTBlobManager else {
+ throw BlobManagerNotFoundException()
+ }
+ return blobManager
+ }
+}
+
+// MARK: Exception definitions
+
+class BridgeNotFoundException: Exception {
+ override var reason: String {
+ "React bridge is null"
+ }
+}
+
+class BlobManagerNotFoundException: Exception {
+ override var reason: String {
+ "Module RCTBlobManager not found"
+ }
+}
+
+class NoSuchBlobException: GenericException<String> {
+ override var reason: String {
+ "No blob data found for blob id=\(param)"
+ }
+}
+
+class BlobCreationFailedException: Exception {
+ override var reason: String {
+ "Failed to store blob"
+ }
+}
diff --git a/native/expo-modules/comm-expo-package/ios/TypedArray+data.swift b/native/expo-modules/comm-expo-package/ios/TypedArray+data.swift
new file mode 100644
--- /dev/null
+++ b/native/expo-modules/comm-expo-package/ios/TypedArray+data.swift
@@ -0,0 +1,12 @@
+import ExpoModulesCore
+
+extension TypedArray {
+ func data() -> Data {
+ Data(bytes: self.rawPointer, count: self.byteLength)
+ }
+
+ func rawBufferPtr() -> UnsafeMutableRawBufferPointer {
+ UnsafeMutableRawBufferPointer(start: self.rawPointer,
+ count: self.byteLength)
+ }
+}
diff --git a/native/utils/blob-utils-module.js b/native/utils/blob-utils-module.js
new file mode 100644
--- /dev/null
+++ b/native/utils/blob-utils-module.js
@@ -0,0 +1,44 @@
+// @flow
+
+import { requireNativeModule } from 'expo-modules-core';
+import RNBlob from 'react-native/Libraries/Blob/Blob.js';
+import BlobManager from 'react-native/Libraries/Blob/BlobManager.js';
+import type { BlobData } from 'react-native/Libraries/Blob/BlobTypes.js';
+
+const BlobUtilsModule: {
+ +copyBlobToTypedArray: (blob: BlobData, destination: Uint8Array) => void,
+ +blobFromTypedArray: (data: $TypedArray) => string,
+} = requireNativeModule('BlobUtils');
+
+function arrayBufferFromBlob(blob: Blob): ArrayBuffer {
+ // $FlowFixMe: react-native Blob type is incompatible with global Blob type
+ const rnBlob = (blob: RNBlob);
+ if (!(rnBlob instanceof RNBlob)) {
+ throw new Error(
+ 'Given blob is not a React Native blob. Missing "data" property.',
+ );
+ }
+ const blobData = rnBlob.data;
+
+ const resultArray = new Uint8Array(blob.size);
+ BlobUtilsModule.copyBlobToTypedArray(blobData, resultArray);
+ return resultArray.buffer;
+}
+
+function blobFromArrayBuffer(arrayBuffer: ArrayBuffer, type?: string): Blob {
+ const typedArray = new Uint8Array(arrayBuffer);
+ const blobID = BlobUtilsModule.blobFromTypedArray(typedArray);
+ const reactNativeBlob = BlobManager.createFromOptions({
+ blobId: blobID,
+ offset: 0,
+ size: arrayBuffer.byteLength,
+ type: type || '',
+ lastModified: Date.now(),
+ });
+
+ // $FlowFixMe: react-native Blob type is incompatible with global Blob type
+ // $FlowFixMe: even though they have the same properties
+ return (reactNativeBlob: Blob);
+}
+
+export { arrayBufferFromBlob, blobFromArrayBuffer };
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 5, 1:17 AM (13 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2615426
Default Alt Text
D7973.diff (5 KB)
Attached To
Mode
D7973: [native] Add BlobUtils expo-module and add iOS implementation
Attached
Detach File
Event Timeline
Log In to Comment