AddSnapshotListener фонового Firestore в iOS - PullRequest
0 голосов
/ 11 октября 2018

Я делаю приложение с Xamarin.Forms для Android и для iOS.Приложению необходимо извлечь список сообществ из Firestore и, если пользователь включит его, оно может подписаться на оповещения в каждом сообществе.

В Android я сделал Sticky Service, который запускается при запуске приложения,а затем в функции OnStartCommand Сервис подписывается для каждого сообщества с помощью AddSnapshotListener (this);функция (ниже пример кода).Все работает нормально, но теперь мне нужно сделать то же самое, но в iOS.

Я провел исследование и попытался изучить фоновую систему в iOS.В документации Microsoft я обнаружил, что в iOS есть фоновый режим, называемый «Fetch», и, насколько я понимаю, это функция в AppDelegate, которая вызывается iOS каждые X секунд / минут.Но вместо Android, где я подписываю приложение на класс, я не могу представить, как я могу использовать AddSnapshotListener в функции, которая вызывается из системы.

Итак, как я могу прослушивать изменения в коллекции Firestoreв фоновом режиме на iOS?

Одним из способов может быть использование Background Fetch и вызов .GetCollection ("community1") и проверка новых документов, но проблема в том, что пользователь может добавить более одного сообщества, а затемможет быть большая проблема с данными в Интернете (также я думаю, что максимум 30 секунд для обратного вызова из функции извлечения, в противном случае iOS может завершить работу приложения).

Вот код, который я используюв Android (я упростил код):

DroidCommonFunctions.cs

    public void UpdateCommunityAlertListener(List<LocalCommunity> Communities)
    {
        if (MainActivity.ThisAct == null || Communities == null)
            return;
        try
        {
            MainActivity.ThisAct.StopService(new Intent(MainActivity.ThisAct, typeof(BackgroundTask.CommunityAlertsListener)));
            if (Communities.Count == 0)
                return;
            Intent serviceIntent = new Intent(MainActivity.ThisAct, typeof(BackgroundTask.CommunityAlertsListener));
            serviceIntent.PutExtra("CommunityLength", Communities.Count);
            for (int i = 0; i < Communities.Count; i++)
            {
                serviceIntent.PutExtra("CommunityId" + i, Communities[i].Id);
                serviceIntent.PutExtra("CommunityName" + i, Communities[i].Alias);
            }
            MainActivity.ThisAct.StartService(serviceIntent);
        } catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("ACAL: " + ex.Message);
        }
    }

DroidBackgroundTask.cs

[Service]
public class CommunityAlertsListener : Service, IEventListener
{
    public class CommunityRegistration
    {
        public string Name { get; set; } = "";
        public IListenerRegistration Registration { get; set; }
    }

    public Dictionary<string, CommunityRegistration> CommunityDic = new Dictionary<string, CommunityRegistration>();

    public override void OnCreate()
    {
        base.OnCreate();
        StartServiceWithNotification(); //Create Android Notification
    }

    [return: GeneratedEnum]
    public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
    {
        if(FirestoreService.Instance == null)
        {
            StopSelf();
            return StartCommandResult.RedeliverIntent;
        }

        int comLength = intent.GetIntExtra("CommunityLength", 0);
        for(int i = 0; i < comLength; i++)
        {
            string comId = intent.GetStringExtra("CommunityId" + i);
            string comName = intent.GetStringExtra("CommunityName" + i);
            if (string.IsNullOrWhiteSpace(comId) || string.IsNullOrWhiteSpace(comName) || CommunityDic.ContainsKey(comId))
                continue;
            IListenerRegistration comReg = FirestoreService.Instance.Collection("communities").Document(comId).Collection("security_events").AddSnapshotListener(this);
            CommunityDic.Add(comId, new CommunityRegistration()
            {
                Name = comName,
                Registration = comReg
            });
        }

        if (comLength == 0 || CommunityDic.Count == 0)
            StopSelf();
        else
            System.Diagnostics.Debug.WriteLine("CommunityAlertsListener STARTED!");

        return StartCommandResult.RedeliverIntent;
    }

    public void OnEvent(Java.Lang.Object value, FirebaseFirestoreException error)
    {
        if (error != null)
        {
            System.Diagnostics.Debug.WriteLine("Listen failed: " + error.Message);
            return;
        }

        try
        {
            QuerySnapshot snapshot = (QuerySnapshot)value;
            if (snapshot.Query == null || snapshot.Query.GetType() != typeof(CollectionReference))
                return;
            NotifySnapshot(snapshot); //Create Android Notification
        }
        catch
        {
            System.Diagnostics.Debug.WriteLine("Listen Failed: " + error.Message);
        }
    }

    public override void OnDestroy()
    {
        foreach(CommunityRegistration comReg in CommunityDic.Values)
        {
            try
            {
                if (comReg != null && comReg.Registration != null)
                    comReg.Registration.Remove();
            } catch
            {
                if (comReg != null)
                    System.Diagnostics.Debug.WriteLine(string.Format("{0} wasn't being removed", comReg.Name));
                else
                    System.Diagnostics.Debug.WriteLine("A community wasn't being removed");
            }
        }
        System.Diagnostics.Debug.WriteLine("CommunityAlertsListener STOPPED!");
        base.OnDestroy();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...