Changeset View
Changeset View
Standalone View
Standalone View
native/expo-modules/comm-expo-package/ios/BlobUtilsModule.swift
- This file was added.
import ExpoModulesCore | |||||
// This type corresponds to the BlobData interface in react-native | |||||
struct BlobMetadata: Record { | |||||
@Field var blobId: String | |||||
atul: Super minor nit but we usually would do something like `blobID` instead of `blobId` | |||||
bartekAuthorUnsubmitted Done Inline ActionsYes, but we need to be in sync with RN internal names here (linked in issue description) bartek: Yes, but we need to be in sync with RN internal names here (linked in issue description) | |||||
atulUnsubmitted Not Done Inline ActionsAh understood, disregard then atul: Ah understood, disregard then | |||||
@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() | |||||
marcinUnsubmitted Not Done Inline ActionsMight be missing swift knowledge but I am under the impression that potential error here is not caught anywhere. marcin: Might be missing swift knowledge but I am under the impression that potential error here is not… | |||||
bartekAuthorUnsubmitted Done Inline ActionsOne line above, the closure is marked as throws (the same meaning as for Java functions). Exceptions are then handled automatically by expo-modules and their message and stack trace is converted to promise rejection / throwing new Error() in JS. bartek: One line above, the closure is marked as `throws` (the same meaning as for Java functions). | |||||
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" | |||||
} | |||||
} |
Super minor nit but we usually would do something like blobID instead of blobId