@capgo/capacitor-uploader 8.2.11 → 8.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -65,6 +65,32 @@ Add the following to your `AndroidManifest.xml` file:
65
65
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
66
66
  ```
67
67
 
68
+
69
+
70
+ ## iOS
71
+
72
+ On iOS the plugin uploads through a background `URLSession` using the identifier `CapacitorUploaderBackgroundSession`.
73
+
74
+ Uploads often work without extra `Info.plist` keys. To allow the system to wake your app when background transfers finish, add the `fetch` background mode:
75
+
76
+ ```xml
77
+ <key>UIBackgroundModes</key>
78
+ <array>
79
+ <string>fetch</string>
80
+ </array>
81
+ ```
82
+
83
+ Do **not** add the `processing` background mode for this plugin alone. App Store Connect requires `BGTaskSchedulerPermittedIdentifiers` whenever `processing` is declared, and this plugin does not register `BGTaskScheduler` tasks. If your app already includes `processing` (for example from older documentation) and validation fails, add:
84
+
85
+ ```xml
86
+ <key>BGTaskSchedulerPermittedIdentifiers</key>
87
+ <array>
88
+ <string>CapacitorUploaderBackgroundSession</string>
89
+ </array>
90
+ ```
91
+
92
+ See [issue #115](https://github.com/Cap-go/capacitor-uploader/issues/115) for context.
93
+
68
94
  ## Example S3 upload
69
95
 
70
96
  ```typescript
@@ -242,6 +268,20 @@ Documentation for the [Capacitor Camera preview](https://github.com/Cap-go/camer
242
268
 
243
269
  Capacitor Uploader Plugin for uploading files with background support and progress tracking.
244
270
 
271
+ ### iOS setup
272
+
273
+ On iOS the native layer uses a background `URLSession` with the identifier
274
+ `CapacitorUploaderBackgroundSession`. Many apps can upload without adding
275
+ `UIBackgroundModes`; add `fetch` when you need uploads to continue after the app
276
+ is suspended.
277
+
278
+ App Store Connect rejects builds that declare `UIBackgroundModes` → `processing`
279
+ without `BGTaskSchedulerPermittedIdentifiers`. This plugin does not schedule
280
+ `BGTaskScheduler` work, so avoid `processing` unless another feature needs it.
281
+ If `processing` is present (for example from older setup guides), include
282
+ `CapacitorUploaderBackgroundSession` in `BGTaskSchedulerPermittedIdentifiers`
283
+ in your app's `Info.plist`.
284
+
245
285
  ### startUpload(...)
246
286
 
247
287
  ```typescript
@@ -29,7 +29,7 @@ public class UploaderPlugin extends Plugin {
29
29
 
30
30
  private static final String CAPACITOR_CONTENT_PATH_PREFIX = "/_capacitor_content_";
31
31
 
32
- private final String pluginVersion = "8.2.11";
32
+ private final String pluginVersion = "8.2.13";
33
33
 
34
34
  private Uploader implementation;
35
35
 
package/dist/docs.json CHANGED
@@ -2,8 +2,12 @@
2
2
  "api": {
3
3
  "name": "UploaderPlugin",
4
4
  "slug": "uploaderplugin",
5
- "docs": "Capacitor Uploader Plugin for uploading files with background support and progress tracking.",
5
+ "docs": "Capacitor Uploader Plugin for uploading files with background support and progress tracking.\n\n### iOS setup\n\nOn iOS the native layer uses a background `URLSession` with the identifier\n`CapacitorUploaderBackgroundSession`. Many apps can upload without adding\n`UIBackgroundModes`; add `fetch` when you need uploads to continue after the app\nis suspended.\n\nApp Store Connect rejects builds that declare `UIBackgroundModes` → `processing`\nwithout `BGTaskSchedulerPermittedIdentifiers`. This plugin does not schedule\n`BGTaskScheduler` work, so avoid `processing` unless another feature needs it.\nIf `processing` is present (for example from older setup guides), include\n`CapacitorUploaderBackgroundSession` in `BGTaskSchedulerPermittedIdentifiers`\nin your app's `Info.plist`.",
6
6
  "tags": [
7
+ {
8
+ "text": "```xml\n<key>UIBackgroundModes</key>\n<array>\n <string>fetch</string>\n</array>\n<key>BGTaskSchedulerPermittedIdentifiers</key>\n<array>\n <string>CapacitorUploaderBackgroundSession</string>\n</array>\n```",
9
+ "name": "example"
10
+ },
7
11
  {
8
12
  "text": "0.0.1",
9
13
  "name": "since"
@@ -184,6 +184,32 @@ export interface UploadEvent {
184
184
  /**
185
185
  * Capacitor Uploader Plugin for uploading files with background support and progress tracking.
186
186
  *
187
+ * ### iOS setup
188
+ *
189
+ * On iOS the native layer uses a background `URLSession` with the identifier
190
+ * `CapacitorUploaderBackgroundSession`. Many apps can upload without adding
191
+ * `UIBackgroundModes`; add `fetch` when you need uploads to continue after the app
192
+ * is suspended.
193
+ *
194
+ * App Store Connect rejects builds that declare `UIBackgroundModes` → `processing`
195
+ * without `BGTaskSchedulerPermittedIdentifiers`. This plugin does not schedule
196
+ * `BGTaskScheduler` work, so avoid `processing` unless another feature needs it.
197
+ * If `processing` is present (for example from older setup guides), include
198
+ * `CapacitorUploaderBackgroundSession` in `BGTaskSchedulerPermittedIdentifiers`
199
+ * in your app's `Info.plist`.
200
+ *
201
+ * @example
202
+ * ```xml
203
+ * <key>UIBackgroundModes</key>
204
+ * <array>
205
+ * <string>fetch</string>
206
+ * </array>
207
+ * <key>BGTaskSchedulerPermittedIdentifiers</key>
208
+ * <array>
209
+ * <string>CapacitorUploaderBackgroundSession</string>
210
+ * </array>
211
+ * ```
212
+ *
187
213
  * @since 0.0.1
188
214
  */
189
215
  export interface UploaderPlugin {
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Configuration options for uploading a file.\n *\n * @since 0.0.1\n */\nexport interface UploadFileOption {\n /**\n * The local file path of the file to upload.\n * Can be a file:// URL or an absolute path.\n *\n * @since 0.0.3\n */\n filePath: string;\n\n /**\n * The form field name for the file part when using multipart upload.\n *\n * If omitted, `uploadOption.fileField` is used (defaults to `'file'`).\n *\n * @since 0.0.3\n */\n fieldName?: string;\n\n /**\n * The MIME type of this file.\n * If not specified, the plugin will attempt to determine it automatically.\n *\n * @since 0.0.3\n */\n mimeType?: string;\n}\n\nexport interface uploadOption {\n /**\n * The local file path of the file to upload.\n * Can be a file:// URL or an absolute path.\n *\n * If you need to upload multiple files in a single multipart request, use `files`.\n *\n * @since 0.0.1\n */\n filePath?: string;\n\n /**\n * Multiple files to upload in a single request.\n *\n * When provided, uploads are sent as `multipart/form-data` with one part per file.\n * Use `fieldName` to control each part name (e.g. `images[]`).\n *\n * Note: `PUT` uploads (e.g. presigned S3 URLs) only support a single file.\n *\n * @since 0.0.3\n */\n files?: UploadFileOption[];\n\n /**\n * The server URL endpoint where the file should be uploaded.\n *\n * @since 0.0.1\n */\n serverUrl: string;\n\n /**\n * The title of the upload notification shown to the user.\n * Android only.\n *\n * @default 'Uploading'\n * @since 0.0.1\n */\n notificationTitle?: string;\n\n /**\n * HTTP headers to send with the upload request.\n * Useful for authentication tokens, content types, etc.\n *\n * @since 0.0.1\n * @example\n * ```typescript\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers: {\n [key: string]: string;\n };\n\n /**\n * The HTTP method to use for the upload request.\n *\n * @default 'POST'\n * @since 0.0.1\n */\n method?: 'PUT' | 'POST';\n\n /**\n * The MIME type of the file being uploaded.\n * If not specified, the plugin will attempt to determine it automatically.\n *\n * @since 0.0.1\n * @example 'image/jpeg', 'application/pdf', 'video/mp4'\n */\n mimeType?: string;\n\n /**\n * Additional form parameters to send with the upload request.\n * These will be included as form data in multipart uploads.\n *\n * @since 0.0.1\n */\n parameters?: { [key: string]: string };\n\n /**\n * The maximum number of times to retry the upload if it fails.\n *\n * @since 0.0.1\n * @default 0\n */\n maxRetries?: number;\n\n /**\n * The type of upload to perform.\n * - 'binary': Uploads the file as raw binary data in the request body\n * - 'multipart': Uploads the file as multipart/form-data\n *\n * @default 'binary' when `method` is `'PUT'`, otherwise `'multipart'`\n * @since 0.0.2\n */\n uploadType?: 'binary' | 'multipart';\n\n /**\n * The form field name for the file when using multipart upload type.\n * Only used when uploadType is 'multipart'.\n *\n * For multi-file uploads via `files`, this is used as the default field name\n * when a file entry does not specify `fieldName`.\n *\n * @default 'file'\n * @since 0.0.2\n */\n fileField?: string;\n}\n\n/**\n * Event emitted during the upload lifecycle.\n *\n * @since 0.0.1\n */\nexport interface UploadEvent {\n /**\n * The current status of the upload.\n * - 'uploading': Upload is in progress\n * - 'completed': Upload finished successfully\n * - 'failed': Upload encountered an error\n *\n * @since 0.0.1\n */\n name: 'uploading' | 'completed' | 'failed';\n\n /**\n * Additional data about the upload event.\n *\n * @since 0.0.1\n */\n payload: {\n /**\n * Upload progress percentage from 0 to 100.\n * Only present during 'uploading' events.\n *\n * @since 0.0.1\n */\n percent?: number;\n\n /**\n * Error message if the upload failed.\n * Only present during 'failed' events.\n *\n * @since 0.0.1\n */\n error?: string;\n\n /**\n * HTTP status code returned by the server.\n * Present during 'completed' and 'failed' events.\n *\n * @since 0.0.1\n */\n statusCode?: number;\n };\n\n /**\n * Unique identifier for this upload task.\n *\n * @since 0.0.1\n */\n id: string;\n}\n\n/**\n * Capacitor Uploader Plugin for uploading files with background support and progress tracking.\n *\n * @since 0.0.1\n */\nexport interface UploaderPlugin {\n /**\n * Start uploading a file to a server.\n *\n * The upload will continue in the background even if the app is closed or backgrounded.\n * Listen to upload events to track progress, completion, or failure.\n *\n * @param options - Configuration for the upload\n * @returns Promise that resolves with the upload ID\n * @throws Error if the upload fails to start\n * @since 0.0.1\n * @example\n * ```typescript\n * const { id } = await Uploader.startUpload({\n * filePath: 'file:///path/to/file.jpg',\n * serverUrl: 'https://example.com/upload',\n * headers: {\n * 'Authorization': 'Bearer token'\n * },\n * method: 'POST',\n * uploadType: 'multipart',\n * fileField: 'photo'\n * });\n * console.log('Upload started with ID:', id);\n * ```\n *\n * @example\n * ```typescript\n * const { id } = await Uploader.startUpload({\n * serverUrl: 'https://api.example.com/upload',\n * method: 'POST',\n * uploadType: 'multipart',\n * files: [\n * { filePath: 'file:///...photo1.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' },\n * { filePath: 'file:///...photo2.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' },\n * ],\n * parameters: { albumId: '7' },\n * headers: { Authorization: 'Bearer token' },\n * });\n * console.log('Upload started with ID:', id);\n * ```\n */\n startUpload(options: uploadOption): Promise<{ id: string }>;\n\n /**\n * Cancel and remove an ongoing upload.\n *\n * This will stop the upload if it's in progress and clean up resources.\n *\n * @param options - Object containing the upload ID to remove\n * @returns Promise that resolves when the upload is removed\n * @throws Error if the upload ID is not found\n * @since 0.0.1\n * @example\n * ```typescript\n * await Uploader.removeUpload({ id: 'upload-123' });\n * ```\n */\n removeUpload(options: { id: string }): Promise<void>;\n\n /**\n * Listen for upload progress and status events.\n *\n * Events are fired for:\n * - Upload progress updates (with percent)\n * - Upload completion (with statusCode)\n * - Upload failure (with error and statusCode)\n *\n * @param eventName - Must be 'events'\n * @param listenerFunc - Callback function to handle upload events\n * @returns Promise that resolves with a listener handle for removal\n * @since 0.0.1\n * @example\n * ```typescript\n * const listener = await Uploader.addListener('events', (event) => {\n * if (event.name === 'uploading') {\n * console.log(`Upload ${event.id}: ${event.payload.percent}%`);\n * } else if (event.name === 'completed') {\n * console.log(`Upload ${event.id} completed`);\n * } else if (event.name === 'failed') {\n * console.error(`Upload ${event.id} failed:`, event.payload.error);\n * }\n * });\n *\n * // Remove listener when done\n * await listener.remove();\n * ```\n */\n addListener(eventName: 'events', listenerFunc: (state: UploadEvent) => void): Promise<PluginListenerHandle>;\n\n /**\n * Get the native Capacitor plugin version.\n *\n * @returns Promise that resolves with the plugin version\n * @throws Error if getting the version fails\n * @since 0.0.1\n * @example\n * ```typescript\n * const { version } = await Uploader.getPluginVersion();\n * console.log('Plugin version:', version);\n * ```\n */\n getPluginVersion(): Promise<{ version: string }>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Configuration options for uploading a file.\n *\n * @since 0.0.1\n */\nexport interface UploadFileOption {\n /**\n * The local file path of the file to upload.\n * Can be a file:// URL or an absolute path.\n *\n * @since 0.0.3\n */\n filePath: string;\n\n /**\n * The form field name for the file part when using multipart upload.\n *\n * If omitted, `uploadOption.fileField` is used (defaults to `'file'`).\n *\n * @since 0.0.3\n */\n fieldName?: string;\n\n /**\n * The MIME type of this file.\n * If not specified, the plugin will attempt to determine it automatically.\n *\n * @since 0.0.3\n */\n mimeType?: string;\n}\n\nexport interface uploadOption {\n /**\n * The local file path of the file to upload.\n * Can be a file:// URL or an absolute path.\n *\n * If you need to upload multiple files in a single multipart request, use `files`.\n *\n * @since 0.0.1\n */\n filePath?: string;\n\n /**\n * Multiple files to upload in a single request.\n *\n * When provided, uploads are sent as `multipart/form-data` with one part per file.\n * Use `fieldName` to control each part name (e.g. `images[]`).\n *\n * Note: `PUT` uploads (e.g. presigned S3 URLs) only support a single file.\n *\n * @since 0.0.3\n */\n files?: UploadFileOption[];\n\n /**\n * The server URL endpoint where the file should be uploaded.\n *\n * @since 0.0.1\n */\n serverUrl: string;\n\n /**\n * The title of the upload notification shown to the user.\n * Android only.\n *\n * @default 'Uploading'\n * @since 0.0.1\n */\n notificationTitle?: string;\n\n /**\n * HTTP headers to send with the upload request.\n * Useful for authentication tokens, content types, etc.\n *\n * @since 0.0.1\n * @example\n * ```typescript\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers: {\n [key: string]: string;\n };\n\n /**\n * The HTTP method to use for the upload request.\n *\n * @default 'POST'\n * @since 0.0.1\n */\n method?: 'PUT' | 'POST';\n\n /**\n * The MIME type of the file being uploaded.\n * If not specified, the plugin will attempt to determine it automatically.\n *\n * @since 0.0.1\n * @example 'image/jpeg', 'application/pdf', 'video/mp4'\n */\n mimeType?: string;\n\n /**\n * Additional form parameters to send with the upload request.\n * These will be included as form data in multipart uploads.\n *\n * @since 0.0.1\n */\n parameters?: { [key: string]: string };\n\n /**\n * The maximum number of times to retry the upload if it fails.\n *\n * @since 0.0.1\n * @default 0\n */\n maxRetries?: number;\n\n /**\n * The type of upload to perform.\n * - 'binary': Uploads the file as raw binary data in the request body\n * - 'multipart': Uploads the file as multipart/form-data\n *\n * @default 'binary' when `method` is `'PUT'`, otherwise `'multipart'`\n * @since 0.0.2\n */\n uploadType?: 'binary' | 'multipart';\n\n /**\n * The form field name for the file when using multipart upload type.\n * Only used when uploadType is 'multipart'.\n *\n * For multi-file uploads via `files`, this is used as the default field name\n * when a file entry does not specify `fieldName`.\n *\n * @default 'file'\n * @since 0.0.2\n */\n fileField?: string;\n}\n\n/**\n * Event emitted during the upload lifecycle.\n *\n * @since 0.0.1\n */\nexport interface UploadEvent {\n /**\n * The current status of the upload.\n * - 'uploading': Upload is in progress\n * - 'completed': Upload finished successfully\n * - 'failed': Upload encountered an error\n *\n * @since 0.0.1\n */\n name: 'uploading' | 'completed' | 'failed';\n\n /**\n * Additional data about the upload event.\n *\n * @since 0.0.1\n */\n payload: {\n /**\n * Upload progress percentage from 0 to 100.\n * Only present during 'uploading' events.\n *\n * @since 0.0.1\n */\n percent?: number;\n\n /**\n * Error message if the upload failed.\n * Only present during 'failed' events.\n *\n * @since 0.0.1\n */\n error?: string;\n\n /**\n * HTTP status code returned by the server.\n * Present during 'completed' and 'failed' events.\n *\n * @since 0.0.1\n */\n statusCode?: number;\n };\n\n /**\n * Unique identifier for this upload task.\n *\n * @since 0.0.1\n */\n id: string;\n}\n\n/**\n * Capacitor Uploader Plugin for uploading files with background support and progress tracking.\n *\n * ### iOS setup\n *\n * On iOS the native layer uses a background `URLSession` with the identifier\n * `CapacitorUploaderBackgroundSession`. Many apps can upload without adding\n * `UIBackgroundModes`; add `fetch` when you need uploads to continue after the app\n * is suspended.\n *\n * App Store Connect rejects builds that declare `UIBackgroundModes` → `processing`\n * without `BGTaskSchedulerPermittedIdentifiers`. This plugin does not schedule\n * `BGTaskScheduler` work, so avoid `processing` unless another feature needs it.\n * If `processing` is present (for example from older setup guides), include\n * `CapacitorUploaderBackgroundSession` in `BGTaskSchedulerPermittedIdentifiers`\n * in your app's `Info.plist`.\n *\n * @example\n * ```xml\n * <key>UIBackgroundModes</key>\n * <array>\n * <string>fetch</string>\n * </array>\n * <key>BGTaskSchedulerPermittedIdentifiers</key>\n * <array>\n * <string>CapacitorUploaderBackgroundSession</string>\n * </array>\n * ```\n *\n * @since 0.0.1\n */\nexport interface UploaderPlugin {\n /**\n * Start uploading a file to a server.\n *\n * The upload will continue in the background even if the app is closed or backgrounded.\n * Listen to upload events to track progress, completion, or failure.\n *\n * @param options - Configuration for the upload\n * @returns Promise that resolves with the upload ID\n * @throws Error if the upload fails to start\n * @since 0.0.1\n * @example\n * ```typescript\n * const { id } = await Uploader.startUpload({\n * filePath: 'file:///path/to/file.jpg',\n * serverUrl: 'https://example.com/upload',\n * headers: {\n * 'Authorization': 'Bearer token'\n * },\n * method: 'POST',\n * uploadType: 'multipart',\n * fileField: 'photo'\n * });\n * console.log('Upload started with ID:', id);\n * ```\n *\n * @example\n * ```typescript\n * const { id } = await Uploader.startUpload({\n * serverUrl: 'https://api.example.com/upload',\n * method: 'POST',\n * uploadType: 'multipart',\n * files: [\n * { filePath: 'file:///...photo1.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' },\n * { filePath: 'file:///...photo2.jpg', fieldName: 'images[]', mimeType: 'image/jpeg' },\n * ],\n * parameters: { albumId: '7' },\n * headers: { Authorization: 'Bearer token' },\n * });\n * console.log('Upload started with ID:', id);\n * ```\n */\n startUpload(options: uploadOption): Promise<{ id: string }>;\n\n /**\n * Cancel and remove an ongoing upload.\n *\n * This will stop the upload if it's in progress and clean up resources.\n *\n * @param options - Object containing the upload ID to remove\n * @returns Promise that resolves when the upload is removed\n * @throws Error if the upload ID is not found\n * @since 0.0.1\n * @example\n * ```typescript\n * await Uploader.removeUpload({ id: 'upload-123' });\n * ```\n */\n removeUpload(options: { id: string }): Promise<void>;\n\n /**\n * Listen for upload progress and status events.\n *\n * Events are fired for:\n * - Upload progress updates (with percent)\n * - Upload completion (with statusCode)\n * - Upload failure (with error and statusCode)\n *\n * @param eventName - Must be 'events'\n * @param listenerFunc - Callback function to handle upload events\n * @returns Promise that resolves with a listener handle for removal\n * @since 0.0.1\n * @example\n * ```typescript\n * const listener = await Uploader.addListener('events', (event) => {\n * if (event.name === 'uploading') {\n * console.log(`Upload ${event.id}: ${event.payload.percent}%`);\n * } else if (event.name === 'completed') {\n * console.log(`Upload ${event.id} completed`);\n * } else if (event.name === 'failed') {\n * console.error(`Upload ${event.id} failed:`, event.payload.error);\n * }\n * });\n *\n * // Remove listener when done\n * await listener.remove();\n * ```\n */\n addListener(eventName: 'events', listenerFunc: (state: UploadEvent) => void): Promise<PluginListenerHandle>;\n\n /**\n * Get the native Capacitor plugin version.\n *\n * @returns Promise that resolves with the plugin version\n * @throws Error if getting the version fails\n * @since 0.0.1\n * @example\n * ```typescript\n * const { version } = await Uploader.getPluginVersion();\n * console.log('Plugin version:', version);\n * ```\n */\n getPluginVersion(): Promise<{ version: string }>;\n}\n"]}
@@ -3,7 +3,7 @@ import Capacitor
3
3
 
4
4
  @objc(UploaderPlugin)
5
5
  public class UploaderPlugin: CAPPlugin, CAPBridgedPlugin {
6
- private let pluginVersion: String = "8.2.11"
6
+ private let pluginVersion: String = "8.2.13"
7
7
  public let identifier = "UploaderPlugin"
8
8
  public let jsName = "Uploader"
9
9
  public let pluginMethods: [CAPPluginMethod] = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-uploader",
3
- "version": "8.2.11",
3
+ "version": "8.2.13",
4
4
  "description": "Upload file natively",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",