|
7 | 7 | // Other code you write will be lost the next time you deploy the project. |
8 | 8 | import { Base64 } from "js-base64"; |
9 | 9 | import RNBlobUtil from "react-native-blob-util"; |
| 10 | +import { NativeModules } from "react-native"; |
10 | 11 |
|
11 | 12 | // BEGIN EXTRA CODE |
12 | 13 | // END EXTRA CODE |
@@ -45,21 +46,38 @@ export async function Base64DecodeToImage(base64: string, image: mendix.lib.MxOb |
45 | 46 | } |
46 | 47 |
|
47 | 48 | // Create a temporary file path |
48 | | - const tempPath = `${RNBlobUtil.fs.dirs.CacheDir}/temp_image_${Date.now()}.png`; |
| 49 | + const fileName = `image_${Date.now()}.png`; |
| 50 | + const tempPath = `${RNBlobUtil.fs.dirs.CacheDir}/${fileName}`; |
49 | 51 |
|
50 | 52 | // Write Base64 data to a temporary file |
51 | 53 | await RNBlobUtil.fs.writeFile(tempPath, cleanBase64, "base64"); |
52 | 54 |
|
53 | | - // Fetch the file as a blob |
54 | | - const res = await fetch(`file://${tempPath}`); |
55 | | - const blob = await res.blob(); |
| 55 | + // Read the file into the native blob store so offline mode works: |
| 56 | + // NativeFileBackend.storeFile calls NativeFileSystem.save(blob.data, path) |
| 57 | + // and blob.close() — a plain object has no .data getter or .close(), which |
| 58 | + // crashes iOS via [NSInvocation invokeWithTarget:]. |
| 59 | + const nativeBlob = await NativeModules.MxFileSystem.read(tempPath.replace("file://", "")); |
| 60 | + // Normalize: MxFileSystem.read may return 'length' instead of 'size'. |
| 61 | + const blobData = { ...(nativeBlob as any) }; |
| 62 | + if (blobData.size === undefined && blobData.length !== undefined) { |
| 63 | + blobData.size = blobData.length; |
| 64 | + } |
| 65 | + const blob = new Blob(); |
| 66 | + Object.assign(blob, { data: blobData }); |
| 67 | + |
| 68 | + // Set nativePayload so the patched FormData.prototype.append in NativeFileBackend |
| 69 | + // replaces the blob value with { uri, name, type } for online uploads. The patch |
| 70 | + // reads the third append() argument (fileName) and writes it onto nativePayload.name, |
| 71 | + // which FormData.getParts() uses as the Content-Disposition filename. |
| 72 | + (blob as any).nativePayload = { uri: `file://${tempPath}`, name: fileName, type: "image/png" }; |
| 73 | + const fileBlob = blob as Blob; |
56 | 74 |
|
57 | 75 | return new Promise((resolve, reject) => { |
58 | 76 | mx.data.saveDocument( |
59 | 77 | image.getGuid(), |
60 | | - "camera image", |
| 78 | + fileName, |
61 | 79 | {}, |
62 | | - blob, |
| 80 | + fileBlob, |
63 | 81 | () => { |
64 | 82 | RNBlobUtil.fs.unlink(tempPath).catch(e => console.info("Temp file cleanup failed:", e)); |
65 | 83 | resolve(true); |
|
0 commit comments