(отредактировано для предоставления обновленной информации)
У меня есть приложение nativescript, которое выполняет различные задачи, которые я хотел бы продолжить, если телефон перейдет в фоновый режим или заблокирован.
Ориентирован на iOS с Nativescript Angular. Я также новичок в использовании кода obj C в Nativescript.
В качестве простого примера предположим, что я хочу печатать на консоли каждые 5 секунд после того, как пользователь нажимает кнопку, поэтому у меня есть следующий код в моем ts-файле компонента:
coolComponent.ts:
@Component({...})
Export class coolComponent {
...
whenButtonClicked(){
setInterval(function(){
console.info('button has been clicked. show every 5 seconds!');
}, 5000);
}
Без дополнительного кода, когда пользователь нажимает кнопку, он будет печатать на консоли каждые 5 секунд, но затем остановится, когда приложение находится в фоновом режиме или телефон заблокирован. Как заставить функцию продолжать выполнение, даже если приложение находится в фоновом режиме или заблокировано?
При просмотре различных источников, таких как здесь (документы NS о фоновом выполнении) и здесь (документы о делегате приложения), похоже, что первым шагом является создание custom-app-delegate, получение его для работы, а затем определение фоновой задачи в info.plist.
Я добился того, чтобы вещи в целом были функциональными, например:
приложение / custom-app-delegate.ts:
import { ios, run as applicationRun } from "tns-core-modules/application";
export class CustomAppDelegate extends UIResponder implements
UIApplicationDelegate {
public static ObjCProtocols = [UIApplicationDelegate];
public applicationDidEnterBackground(application: UIApplication) {
console.info('in background mode!')
}
}
main.ts:
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
import { AppModule } from "./app.module";
import * as application from "tns-core-modules/application";
import { CustomAppDelegate } from "./custom-app-delegate";
application.ios.delegate = CustomAppDelegate;
platformNativeScriptDynamic().bootstrapModule(AppModule);
приложение / app.module.ts:
import { CustomAppDelegate } from "./custom-app-delegate";
приложение / App_Resources / iOS / info.plist:
...
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
изменить: создать ссылку.d.ts:
/// <reference path = "./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path = "./node_modules/tns-platform-declarations/android.d.ts" />
Edit: FYI, чтобы заставить custom-app-delegate работать, мне также пришлось загрузить «tns-platform-declerations» с помощью команды:
$ npm i tns-platform-declarations --save-dev
При этом приложение правильно читает "в фоновом режиме!" когда приложение переходит в фоновый режим. Итак, пользовательский-делегат-приложение работает.
Однако в примерах в Интернете предполагается, что код в custom-app-delegate не зависит от остальной части приложения, поэтому они предполагают, что есть новые задачи, которые нужно выполнить, когда приложение переходит в фоновый режим.
Здесь дело обстоит не так. У меня есть задача, которая выполняется функцией coolComponent, и когда приложение переходит в фоновый режим или заблокировано, я хочу, чтобы это выполнялось в Продолжить.
Вероятно, для этого требуется, чтобы coolComponent.ts взаимодействовал с custom-app-delegate, но я не знаю, как это сделать.
Простое повторение кода в обоих файлах - наличие функции setInterval как в coolComponent.ts, так и в custom-app-delegate - не работает, потому что это не приведет к тому, что custom-app-delegate продолжит работу в тот же момент времени, что и начался. в coolComponent.ts после того, как пользователь нажал кнопку.
Итак, как я могу запустить код в coolComponent.ts и Продолжить после того, как приложение находится в фоновом режиме?
Я не понял, как выполнять фоновые задачи с помощью делегата приложения. Вместо этого я попытался найти другие решения (где другие люди это догадались). Например, я использовал плагин локальных уведомлений nativescript для планирования и последующего отображения уведомлений пользователя, даже если приложение находится в фоновом режиме.





Технически вы не можете заставить свое приложение быть активным, когда пользователь больше не хочет, чтобы оно было активным (заблокировав телефон / свернув приложение). Если вам нравится запускать что-либо в фоновом режиме, вам придется использовать фоновая выборка в iOS.
Это не ситуация, когда «пользователь не хочет, чтобы приложение было активным». Идея состоит в том, что приложение может работать, даже если пользователь кладет его в карман (и блокирует его, чтобы случайно не нажать кнопки). Базовые приложения iphone имеют такую функциональность: так работают карты, музыка, часы и подкасты. "Fetch" был бы правильным способом сделать это, скажем, для таймера обратного отсчета, который работает в фоновом режиме?
Существуют разные типы фоновых режимов, в том числе один для определения местоположения, выборки данных и т. д. Вы должны выбрать тот, который соответствует вашим требованиям. Но на высоком уровне идея заключается в том, что вы не можете поддерживать работу обычного кода приложения после его отправки в фоновый режим.
Я изучал выполнение в фоновом режиме. Я добавил фоновый режим выборки в info.plist, но, похоже, чтобы он работал, вам сначала нужно добавить custom-app-delegate и заставить его работать через такие вещи, как установка tns-platform-деклараций. Я сделал это и смог заставить custom-app-delegate работать - он может регистрироваться, когда приложение переходит в фоновый режим. Но...
Как мне «продолжить» код, который есть в моем файле main.ts, когда приложение перейдет в фоновый режим? Примеры, которые я видел, предполагают, что существуют определенные действия, которые нужно предпринять, когда приложение находится в фоновом режиме. В моем случае (как и в большинстве?) Приложение выполняет задачу - например, таймер в файле main.ts - а затем я хочу, чтобы этот код продолжал выполняться, когда приложение переходит в фоновый режим. Это может включать обмен данными между моим файлом main.ts и custom-app-delegate, но я пытаюсь понять это. Есть ли пример кода о том, что действие происходит в основном ts-файле, а затем оно ПРОДОЛЖАЕТСЯ после фонового режима?
Apple хочет, чтобы разработчик следовал определенным правилам, поэтому лучшее, что вы можете сделать, - это поделиться кодом. Запишите всю свою логику в отдельный файл и вызовите его в приложении и сделайте то же самое из фонового выполнения.
Спасибо. Я обновил свой ответ, чтобы предоставить более подробную информацию и код. Я считаю, что вызова кода из одного файла, а затем из другого было бы недостаточно, потому что повторный вызов кода, когда приложение переходит в фоновый режим, приведет к его запуску заново. Возможно, нужен какой-то процесс, чтобы сообщить приложению, где находится таймер, когда он переходит в фоновый режим ... но я думаю, это может стать слишком сложным. Есть ли более простое решение?
iOS позволяет запускать код в фоновом режиме только в определенных ситуациях. Например (но не ограничиваясь этим):
Если ваше приложение не соответствует ни одной из доступных категорий, лучшее, что вы можете сделать, - это запросить у iOS больше времени для работы в фоновом режиме (по умолчанию 10 секунд). Это позволит вам бежать еще 3 минуты. Просто продолжайте выполнять задачу в бесконечном цикле и аккуратно завершите приложение до истечения предоставленных 180 секунд.
Что касается фоновой выборки, этот механизм позволяет приложениям обновлять свое содержимое в фоновом режиме. iOS будет выполнять приложения, которые объявляют фоновую выборку не реже одного раза в день, поэтому вы в своем делегате можете выполнять обновление с сервера. Этот механизм не подходит для того, что вы ищете.
Привет, у меня такая же проблема. Вы нашли решение? Если да, то дайте мне знать, как с этим справиться.