[Xamarin] 백그라운드에서 정기적으로 처리하는 방법

개요



iOS에서는 본 기사대로 구현함으로써 앱이 백그라운드로 옮겨진 경우에도 여러가지 처리시킬 수 있습니다.
이번은 백그라운드로 옮겨도, 처리가 정지하지 않고, 일정 타이밍으로 이벤트를 발생시키는 방법을 씁니다.

2016/9/25 추가
제목에 "Xamarin.Forms.iOS"라고 썼지만,
오해를 초래하는 기재이므로 수정했습니다.
또, 말미의 코멘트에서 shaga씨에게 가르쳐 주신 대로,
위치 정보를 사용하지 않고 백그라운드 처리가 가능하기 때문에,
순수하게 백그라운드의 처리를 알고 싶은 분은, 코멘트란을 확인해 주세요.
조사 방법이 좋지 않았습니다. 반성・・・.

백그라운드 처리 구현 준비



Xamarin.Forms에서 백그라운드 처리를 구현하려면 iOS의 '위치 서비스' 설정이 필요합니다.
원래 iOS의 백그라운드 처리를 실시하기 위해서는, 위치 정보를 취득하는 CLOcationManagerDelegate 클래스를 계승해, 로직을 짜넣을 필요가 있어, PCL만으로는 구현할 수 없는 구조가 되고 있습니다. (다른 방법도 있는 것 같습니다만 이번은 위치 정보로 실장합니다.)
따라서 iOS 측의 설정이 필수이며, 이 설정이 부족하면 백그라운드의 로직을 구현해도 정상적으로 움직이지 않습니다.

info.plist 설정



배경 모드 설정



백그라운드 모드(Background Modes)에서 위치 정보 업데이트(Location updates)를 선택합니다.


Location Always Usage Description 추가



새 항목 추가에서 Location Always Usage Description을 추가하고 문자열을 설정합니다.
이 설정은 위치 정보를 사용할 때 확인 메시지에 표시되는 문자열입니다.
이 설정을 수행하지 않으면 후속 로직을 포함해도 백그라운드에서 처리되지 않습니다.


아래의 빨간색 프레임 부분에 표시됩니다.


백그라운드 처리를 위한 클래스 추가



iOS 프로젝트에 다음 클래스를 추가합니다.

BackgroundManager.cs
using System;
using System.Threading;
using CoreLocation;

namespace BackgroundTest.iOS
{
    public class BackgroundManager : CLLocationManagerDelegate
    {
        private Timer _timer;
        private CLLocationManager _locationManager;
        private int _starttime = 0;         //タイマーの開始時刻(ミリ秒)
        private int _interval = 1 * 1000;   //呼び出し間隔(ミリ秒)

        public BackgroundManager()
        {
            _locationManager = new CLLocationManager();

            if (CLLocationManager.LocationServicesEnabled)
            {
                _locationManager.Delegate = this;
                _locationManager.DesiredAccuracy = CLLocation.AccurracyBestForNavigation;
                _locationManager.ActivityType = CLActivityType.Fitness;
                _locationManager.PausesLocationUpdatesAutomatically = false;
                _locationManager.DistanceFilter = 1.0;
                _locationManager.AllowsBackgroundLocationUpdates = true;
                _locationManager.RequestAlwaysAuthorization();
                _timer = new Timer(new TimerCallback(CallWriteLine));
            }
        }

        public void Start()
        {
            _timer.Change(_starttime, _interval);
            _locationManager.StartUpdatingLocation();
        }

        public void Stop()
        {
            _timer.Change(Timeout.Infinite, Timeout.Infinite);
            _locationManager.StopUpdatingLocation();
        }

        private static void CallWriteLine(object args)
        {
            Console.WriteLine(DateTime.Now.ToString());
        }
    }
}

Timer 클래스의 TimerCallback 에서, 정기적으로 처리시키고 싶은 메소드를 호출하는 설정을 실시해, 호출처의 CallWriteLine 로, 현재 시각을 출력할 뿐의 로직을 짜넣고 있습니다.

또, Timer 클래스의 Change 메소드로, 인터벌을 설정할 필요가 있어, 이번은 1,000밀리 세컨드를 지정해, 1초 마다 CallWriteLine를 호출하도록 하고 있습니다.
※CLLocationManager에 대해서는, 본 기사의 마지막 URL에 상세가 기재되어 있습니다.

백그라운드 처리 호출



백그라운드 처리를 호출합니다.
이번에는 앱을 시작할 때 백그라운드 처리를 호출하기 위해 iOS 프로젝트의 AppDelegate.cs에 설명합니다.

AppDelegate.cs
using Foundation;
using UIKit;

namespace BackgroundTest.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        BackgroundManager _backgroundManager = null;

        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();

            _backgroundManager = new BackgroundManager();
            _backgroundManager.Start();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }
    }
}

백그라운드 처리 확인



앞에서 설명한 설정과 로직을 내장한 후 실제로 시작시켜 확인합니다.
시작 후 홈 버튼을 누르고 홈 화면 상태에서도 로그가 출력되면 성공입니다.
  • 처음 시작할 때 다음 메시지가 표시되므로 권한을 선택합니다.
  • 권한이 부여된 후 응용 프로그램 출력을 확인하여 초당 로그가 표시되는지 확인합니다.
  • 홈 버튼을 눌러 홈 화면이 표시되고 있는 상태에서 2와 같이 로그가 계속 출력되면 성공입니다.

  • 참고



    Takahiro Octopress Blog - Background에서 위치 정보를 얻으십시오!
    htp : // g 란 ​​d 와 g. 기주 b. 이오/bぉg/2013/09/27/ぉ카치온-s 치메 r/

    좋은 웹페이지 즐겨찾기