Backround ( при отправке приложения в фоновый режим с помощью кнопки home ) в IOS немного сложнее. Вы можете достичь несколькими способами
1) beginBackgroundTaskWithExpirationHandler, но имеет некоторое ограничение во времени
2) событие locationUpdate - но с таймером оно будет работать не очень хорошо. это более пригодно, когда вам нужно время от времени проверять что-либо
3) Сделай себе приложение Player. Плеер может работать даже в фоновом режиме
Я использую метод 3, и он прекрасно работает для меня
Вам необходимо добавить разрешение для фонового звука в файле plist
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Тогда в вашем AppDelegate
вам нужно изменить FinishedLaunching
метод
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
...
var currentSession = AVAudioSession.SharedInstance();
currentSession.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.MixWithOthers);
currentSession.SetActive(true);
...
}
И добавить следующий раздел, я тоже вставил в AppDelegat
#region Background Work
private BackgroundTask _backgroundTask;
private readonly Lazy<TouchLogger> _logger = new Lazy<TouchLogger>(() => new TouchLogger());
public override void DidEnterBackground(UIApplication uiApplication)
{
base.DidEnterBackground(uiApplication);
startBackgroundTask();
}
public override void WillEnterForeground(UIApplication uiApplication)
{
base.WillEnterForeground(uiApplication);
if (_backgroundTask == null)
{
_backgroundTask = new BackgroundTask(_logger.Value);
}
else if (_backgroundTask.IsRunned)
{
_backgroundTask.Stop();
_logger.Value.Info("Background", "Task stopped");
}
}
private void startBackgroundTask()
{
_logger.Value.Info("Background", "startBackgroundTask() called");
var needBackgroundActivity = true;// if you timer is running set true, if not false
if (needBackgroundActivity)
{
if (_backgroundTask == null)
_backgroundTask = new BackgroundTask(_logger.Value);
_backgroundTask.Start();
_logger.Value.Info("Background", "Task runned");
}
}
private class BackgroundTask
{
private const string EmptySoundFileName = "Sounds/empty";//wav file, I use 4 sec long file with no sound
private TouchLogger _logger;
private AVAudioPlayer _player;
private NSTimer _debugTimer;
public bool IsRunned { get; private set; }
public BackgroundTask(TouchLogger logger)
{
_logger = logger;
}
public void Start()
{
IsRunned = true;
if (_player != null && _player.Playing)
{
Stop();
}
var bundle = NSBundle.MainBundle.PathForResource(EmptySoundFileName, "wav");
var sound = new NSUrl(bundle);
_player = AVAudioPlayer.FromUrl(sound);
_player.NumberOfLoops = -1;
_player.Volume = 0.1f;
_player.PrepareToPlay();
_player.Play();
startDebugTimer();
}
public void Stop()
{
IsRunned = false;
if (_player != null && _player.Playing)
{
_player.Stop();
_player.Dispose();
_player = null;
}
stopTimer(ref _debugTimer);
}
private void startDebugTimer()
{
initAndStartTimer(ref _debugTimer, 5,
() => _logger.Value.Info("Background", "Background is fine!"));
}
private void initAndStartTimer(ref NSTimer timer, int intervalMin, Action action)
{
timer?.Invalidate();
if (action != null)
timer =
NSTimer.CreateRepeatingScheduledTimer(
TimeSpan.FromMinutes(intervalMin),
t => action());
}
private void stopTimer(ref NSTimer timer)
{
timer?.Invalidate();
timer = null;
}
}
#endregion
TouchLogger
- отправьте несколько сообщений на консоль, для проверки фона вы можете удалить их. То же самое с _debugTimer
, это просто записывает состояние фонового рабочего каждые 5 минут.
Если что-то не работает, скажите мне, я сделал это давным-давно, поэтому, возможно, что-то пропустил