diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 1e7d8d3b..11437995 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -28,7 +28,7 @@ iOS requires a 5-minute setup in Xcode. Choose your approach based on your needs #### Option A: Periodic Tasks (Recommended for most use cases) For regular data sync, notifications, cleanup - uses iOS Background Fetch: -1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist: +1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)): ```xml UIBackgroundModes @@ -45,7 +45,7 @@ For regular data sync, notifications, cleanup - uses iOS Background Fetch: #### Option B: Processing Tasks (For complex operations) For file uploads, data processing, longer tasks - uses BGTaskScheduler: -1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist: +1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)): ```xml UIBackgroundModes @@ -75,7 +75,7 @@ WorkmanagerPlugin.registerBGProcessingTask( #### Option C: Periodic Tasks with Custom Frequency For periodic tasks with more control than Background Fetch - uses BGTaskScheduler with frequency: -1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist: +1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)): ```xml UIBackgroundModes diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 63dad78d..68b19d82 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,33 +1,46 @@ PODS: - Flutter (1.0.0) + - integration_test (0.0.1): + - Flutter - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - permission_handler_apple (9.3.0): - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS - workmanager_apple (0.0.1): - Flutter DEPENDENCIES: - Flutter (from `Flutter`) + - integration_test (from `.symlinks/plugins/integration_test/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - workmanager_apple (from `.symlinks/plugins/workmanager_apple/ios`) EXTERNAL SOURCES: Flutter: :path: Flutter + integration_test: + :path: ".symlinks/plugins/integration_test/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" workmanager_apple: :path: ".symlinks/plugins/workmanager_apple/ios" SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e path_provider_foundation: 608fcb11be570ce83519b076ab6a1fffe2474f05 permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 workmanager_apple: 904529ae31e97fc5be632cf628507652294a0778 PODFILE CHECKSUM: 1959d098c91d8a792531a723c4a9d7e9f6a01e38 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 01efe3a0..485a9645 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -369,12 +369,16 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", + "${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework", "${BUILT_PRODUCTS_DIR}/workmanager_apple/workmanager_apple.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/workmanager_apple.framework", ); runOnlyForDeploymentPostprocessing = 0; diff --git a/workmanager_android/android/src/main/kotlin/dev/fluttercommunity/workmanager/BackgroundWorker.kt b/workmanager_android/android/src/main/kotlin/dev/fluttercommunity/workmanager/BackgroundWorker.kt index ef2a37ad..367b3bd7 100644 --- a/workmanager_android/android/src/main/kotlin/dev/fluttercommunity/workmanager/BackgroundWorker.kt +++ b/workmanager_android/android/src/main/kotlin/dev/fluttercommunity/workmanager/BackgroundWorker.kt @@ -46,7 +46,7 @@ class BackgroundWorker( } private val dartTask - get() = workerParams.inputData.getString(DART_TASK_KEY)!! + get() = workerParams.inputData.getString(DART_TASK_KEY) private val runAttemptCount = workerParams.runAttemptCount private val randomThreadIdentifier = Random().nextInt() @@ -86,11 +86,20 @@ class BackgroundWorker( return@ensureInitializationCompleteAsync } + val localDartTask = dartTask + + if (localDartTask == null) { + val exception = IllegalStateException("Dart task is null") + WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception) + completer?.set(Result.failure()) + return@ensureInitializationCompleteAsync + } + val dartBundlePath = flutterLoader.findAppBundlePath() val taskInfo = TaskDebugInfo( - taskName = dartTask, + taskName = localDartTask, inputData = payload, startTime = startTime, callbackHandle = callbackHandle, @@ -132,9 +141,18 @@ class BackgroundWorker( ) { val fetchDuration = System.currentTimeMillis() - startTime + val localDartTask = dartTask + + if (localDartTask == null) { + val exception = IllegalStateException("Dart task is null") + WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception) + completer?.set(Result.failure()) + return + } + val taskInfo = TaskDebugInfo( - taskName = dartTask, + taskName = localDartTask, inputData = payload, startTime = startTime, ) @@ -175,7 +193,17 @@ class BackgroundWorker( // Convert payload to the format expected by Pigeon (Map) val pigeonPayload = payload.mapKeys { it.key as String? }.mapValues { it.value as Object? } - flutterApi.executeTask(dartTask, pigeonPayload) { result -> + val localDartTask = dartTask + + if (localDartTask == null) { + val exception = IllegalStateException("Dart task is null") + WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception) + + stopEngine(Result.failure(), exception.message) + return + } + + flutterApi.executeTask(localDartTask, pigeonPayload) { result -> when { result.isSuccess -> { val wasSuccessful = result.getOrNull() ?: false