Bjorn Holmthorsson Ответов: 0

Xamarin формирует фоновые задачи iOS


Я пытаюсь заставить фоновые задачи работать на IOS с помощью c# и visual studio. Я использую фреймворк BGTaskScheduler. Я сначала регистрирую задачу, когда приложение переходит в фоновый режим, а затем оно должно ударить через 2 минуты, установив:
EarliestBeginDate = (NSDate)DateTime.Now.AddMinutes(2)


Задача никогда не запускается, поэтому фоновые задачи как будто не знают о запланированной задаче. У кого-нибудь раньше была подобная проблема? Я использую c#, потому что хочу, чтобы большинство кодов были одинаковыми на IOS и Android, если я делаю аналогичное кодирование с помощью SWIFT и xcode, то это действительно работает, просто в Visual Studio с использованием c# это не работает. Вот код, он есть на github. : Гитхаб - sigthor/фон.пинг[^]

Что я уже пробовал:

Это мое расписание proc:
private void ScheduleAppPing()
       {
           try
           {
               Analytics.TrackEvent("Scheduling location background task", new Dictionary<string, string> { { "user", App.User?.Id } });
               Debug.WriteLine("Scheduling location background task.");

               var request = new BGAppRefreshTaskRequest(PingTaskId)
               {
                   //EarliestBeginDate = (NSDate)DateTime.Now.AddMinutes(2) // Fetch no earlier than 10 minutes from now
                   //EarliestBeginDate = (NSDate)DateTime.Now.AddSeconds(30) // Fetch no earlier than 10 minutes from now
                   EarliestBeginDate = null
               };

               BGTaskScheduler.Shared.Submit(request, out NSError error);

               if (error != null)
               {
                   throw new Exception(error.LocalizedDescription);
               }
           }
           catch (Exception ex)
           {
               Crashes.TrackError(ex);
               Debug.WriteLine($"Error while trying to schedule a background task.: [{ex.Message}]");
           }
       }


и это мое событие handleapping, которое должно быть вызвано
private void HandleAppPing(BGAppRefreshTask task)
        {
            // Schedule the next task (Periodic scheduling)
            ScheduleAppPing();

            task.ExpirationHandler = () =>
            {
                task.SetTaskCompleted(false);
                urlSession.GetAllTasks((tasks) =>
                {
                    tasks.ForEach(t =>
                    {
                        t.Cancel();
                    });
                    urlSession.InvalidateAndCancel();
                });
                
            };

            Debug.WriteLine("Location ping started.");
            Analytics.TrackEvent("Location background task started", new Dictionary<string, string> { { "user", App.User?.Id } });

            try
            {
                var location = App.User?.LastLocation;
                if (location != null)
                {
                    var url = service.GenerateUpdateLocationUrl(App.User?.Id, location.Longitude, location.Latitude);

                    Analytics.TrackEvent("Location background url", new Dictionary<string, string> { { "user", App.User?.Id }, { "url", url } });
                                        
                    var urlRequest = NSUrlRequest.FromUrl(NSUrl.FromString(url));
                    urlSession.CreateDataTask(urlRequest, (data, response, error) => {
                        if (error != null)
                        {
                            var ex = new Exception(error.LocalizedDescription);
                            Crashes.TrackError(ex);
                            Debug.WriteLine($"Error while sending location in a background task.: [{ex.Message}]");

                            task.SetTaskCompleted(false);
                        }
                        else
                        {
                            task.SetTaskCompleted(true);
                        }
                    });
                }
                else
                {
                    Analytics.TrackEvent("Location background task is missing the location!", new Dictionary<string, string> { { "user", App.User?.Id } });

                    task.SetTaskCompleted(false);
                }                
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
                Debug.WriteLine("Error while updating location in scheduled background task.");

                task.SetTaskCompleted(false);
            }
        }

Gerry Schmitz

Что не так с этим .NET Backgroundworker?

Ravi Bhavnani

Я думаю, что OP хочет, чтобы код запускался, когда приложение является фоновым, что, по моему мнению, отличается от BackgroundWorker (который запускает код в потоке, отличном от основного потока пользовательского интерфейса).

/Рави

Gerry Schmitz

Вы информированы лишь частично. BGW может обновить поток пользовательского интерфейса с помощью события ProgressChanged.

Ravi Bhavnani

Я думал, что BGW, инициированный пользовательским интерфейсом приложения, не будет выполняться, когда приложение будет фоновым, хотя служба будет продолжать выполняться. Может быть, я ошибаюсь?

/Рави

Gerry Schmitz

Окно является "активным" или нет (оно имеет или не имеет фокуса); оно не является "фоновым". BGW может обновить окно независимо от того, имеет ли оно фокус или нет: это просто "свойства". Вам нужно придерживаться терминов, которые вы понимаете.

Ravi Bhavnani

Спасибо за разъяснение. Я предполагаю, что приложение станет фоновым только тогда, когда состояние активности будет "остановлено".

/Рави

0 Ответов