Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐞iOS: registerOneOffTask never registers with callbackDispatcher #450

Closed
4 tasks done
ChristopherBrislin opened this issue Dec 12, 2022 · 11 comments
Closed
4 tasks done
Labels
bug Something isn't working

Comments

@ChristopherBrislin
Copy link

  • I have read the README
  • I have done the setup for Android
  • I have done the setup for iOS
  • I have ran the sample app and it does not work there

Version

Technology Version
Workmanager version 0.5.0
Xcode version 14.1
Swift version 5.7.1
iOS deployment target 11.0

Describe the error

Have followed all the directions in the iOS setup and guides but am unable to get the plugin to work correctly. No errors are thrown - the callback dispatcher is just never called. The code works without fault on Android. The test environment is a physical device (iPhone XS running iOS 16.1.2) and is being debugged from XCode. The Info.plist has been configured with the correct task indentifier and backgroundFetch seems to work as expected and triggers the callbackDispatcher, but registering a one off task doesn't.

callbackDispatcher as top level function:

void callbackDispatcher() {
  Workmanager().executeTask((taskName, inputData) {
    stderr.writeln(
        'Flutter VM, BACKGROUND TASK: Background task called! $taskName, extra data: $inputData');

    return Future.value(true);
  });
}

my AppDelegate.swift:

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {

  override func userNotificationCenter(_ center: UNUserNotificationCenter,
                                         willPresent notification: UNNotification,
                                         withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
         completionHandler(.alert) // shows banner even if app is in foreground
     }
    
  

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
      // This is required to make any communication available in the action isolate.
        UNUserNotificationCenter.current().delegate = self
        FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
          GeneratedPluginRegistrant.register(with: registry)
        }
        //WorkmanagerPlugin.register(with: self!.registrar(forPlugin: "com.v2software.onchocks.onchocks-background-logging"))
        WorkmanagerPlugin.registerTask(withIdentifier: "com.v2software.onchocks.onchocks-background-logging")
      
        UIApplication.shared.setMinimumBackgroundFetchInterval(TimeInterval(60*15))
        GeneratedPluginRegistrant.register(with: self)
        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
        }
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

I'm calling registerOneOffTask from a Popupmenuitem:

PopupMenuItem(
                              child: const Text('Record flight'),
                              onTap: () async {
                                print('Registering new task');
                                try {
                                  await Workmanager().registerOneOffTask(
                                      'com.v2software.onchocks.onchocks-background-logging',
                                      'com.v2software.onchocks.onchocks-background-logging',
                                      tag: 'ThisIsANewTag',
          
                                      inputData: {
                                        'user': user?.user.uid,
                                        'registeredEvent': true,
                                      },
                                      initialDelay: Duration.zero,
                                      existingWorkPolicy:
                                          ExistingWorkPolicy.replace);
                                } catch (err) {
                                  print(err.toString());
                                }
                              },
                            ),

When calling the onTap function this is the debug output:

2022-12-12 21:03:51.281401+1030 Runner[3948:242838] flutter: Registering new task
2022-12-12 21:04:17.589698+1030 Runner[3948:254976] [tcp] tcp_input [C2.1.1:3] flags=[R] seq=4218016391, ack=0, win=0 state=LAST_ACK rcv_nxt=4218016391, snd_una=1941703970
2022-12-12 21:04:17.592510+1030 Runner[3948:254976] [tcp] tcp_input [C2.1.1:3] flags=[R] seq=4218016391, ack=0, win=0 state=CLOSED rcv_nxt=4218016391, snd_una=1941703970
2022-12-12 21:04:17.593167+1030 Runner[3948:254976] [tcp] tcp_input [C2.1.1:3] flags=[R] seq=4218016391, ack=0, win=0 state=CLOSED rcv_nxt=4218016391, snd_una=1941703970

I noticed that the callback will fire at a very random time (not associated with any input or background fetch) and the task will be in the queue but missing the input data.

I was expecting behaviour similar to what I am seeing in Android where the callback function is triggered nearly immediately upon registering the task. Am I missunderstanding the functionality of this package or have I missused it?

**[✓] Flutter (Channel stable, 3.0.3, on macOS 13.0.1 22A400 darwin-x64, locale en-AU)
• Flutter version 3.0.3 at /Users/ChrisBrislin/Developer/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 676cefaaff (6 months ago), 2022-06-22 11:34:49 -0700
• Engine revision ffe7b86a1e
• Dart version 2.17.5
• DevTools version 2.12.2

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at /Users/ChrisBrislin/Library/Android/sdk
• Platform android-33, build-tools 33.0.0
• Java binary at: /Applications/Android
Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)

[✓] IntelliJ IDEA Community Edition (version 2021.3.2)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.74.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.54.0

[✓] Connected device (4 available)
• Chris iphone (mobile) • 00008020-001870340E92002E • ios
• iOS 16.1.2 20B110
• iPhone 14 (mobile) • 91A06788-785D-40B3-AEA8-77AED473ECCF • ios
• com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
• macOS (desktop) • macos • darwin-x64
• macOS 13.0.1 22A400 darwin-x64
• Chrome (web) • chrome • web-javascript
• Google Chrome 108.0.5359.98

[✓] HTTP Host Availability
• All required HTTP hosts are available

• No issues found!**

@ChristopherBrislin ChristopherBrislin added the bug Something isn't working label Dec 12, 2022
@minhtritc97
Copy link

same issue on iOS 16

@delfme
Copy link
Contributor

delfme commented Dec 31, 2022

This happens to me as well. Don't paste code because it happens also with plugin's example.

If I run example on android, it works perfectly.
If I run it on ios (on device, ios 16.1.1), I get no errors, but task never executes.
I was expecting the task to be triggered instantly as it happens on android.

@xunreal75
Copy link
Contributor

Hi, I inspected the behavior.
I upgraded flutter to latest release and my iPhone runs with iOS 16.2.
The BGAppRefresh finishes completely. I can see this in debugger notifications. The elapsed time refers to the sleeping time in flutter part.

The issue at the moment seems the isolated SharedPrefs on iOS .
The values are only updated after restart the app.
Therefore I added extra code in my environment today for test purposes.
But this is a SharedPrefs issue which is not to solve at the moment.

I consider to write the data's to an extra file without storing in SharedPrefs.

Be aware iOS is arbitrary and BGRefresh doesn't start like an Android BGTask. Sometimes on iOS the task is called after few minutes, sometimes after two hours.

Please tell me what you want to do. Perhaps I can add a helpful sample code snippet.

@delfme
Copy link
Contributor

delfme commented Jan 4, 2023

@xunreal75 thx for the kind help.
Currently Im using workmanager to run a backup task. Im aware that we dont have scheduledtask on ios but thought that task would have run instantly when app is in foreground.

The need is to have task running for at least 20-30sec even if user moves app to background

@xunreal75
Copy link
Contributor

Hi

I think your idea is the wrong approach.
The interval is too short. iOS doesn't give you the resources for that.
In foreground Flutter can do this, but in background I see no solution.

You could use notifications to wake up the app in background. This will happen a lot of battery duscharge.

@delfme
Copy link
Contributor

delfme commented Jan 5, 2023

Hi

I think your idea is the wrong approach. The interval is too short. iOS doesn't give you the resources for that. In foreground Flutter can do this, but in background I see no solution.

You could use notifications to wake up the app in background. This will happen a lot of battery duscharge.

Yea, noticed that. We will do incremental daily backup. Data will be <30MB which can be uploaded in <20sec over wifi. Silent notifications from server are killed by ios in many occasion, we use Once to run a background task 2 times a day from foreground state

@pradeep-spikey-tech
Copy link

Hi there,
I have the same issue with iOS. Is there a workaround such as an older stable version to alleviate the problem for now?
Would appreciate some kind of input from anybody who has testest a stable version for both iOS and Android.

@xunreal75
Copy link
Contributor

Hi.

I'm recoding at the moment the OnOffTask and looking for other issues.

Further the SharedPrefs reading in isolated doesn't update - updates are only visible after restart app.

I'll solve that by writing log to local filesystem.

There are some (strange) restrictions in iOS.

At the moment the Task starts as AppRefreshTask - means the task starts at any time when iOS like to start.

  1. I will code OnOffTask to start immediately as background task. Problem is that the task can only run 30seconda before IOS will stop it.
    Long running tasks are not possible on this way.

  2. AppRefresh task starts randomly more often as BGProcessingtask. Runs maximum 29 seconds.

  3. BGProcessingTask can run longtime Tasks in background but it's a little bit tricky because you can't run limitless.

@CharanjeetRPOPS
Copy link

Facing same issue on Ios, Any updates on this ?

@absar
Copy link
Contributor

absar commented Sep 11, 2023

@xunreal75 were you able to finalize your solution, if yes could you share the outcome

Further the SharedPrefs reading in isolated doesn't update - updates are only visible after restart app.

If you mean on the dart side then you can use SharedPreferences.getInstance().reload() to get fresh data

@ened
Copy link
Collaborator

ened commented Sep 24, 2023

Many good points in this thread.
Work on extending background process duration is planned as part of #295.

Will close this ticket in favor of that one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants