如何在ios中永远运行后台服务以同步数据 [英] How to run background service in ios forever for syncing of data

查看:25
本文介绍了如何在ios中永远运行后台服务以同步数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,它需要在 Web 服务器上进行同步操作(数据提交和检索).

Hi I am developing an App which has a requirement to do syncing operation (data submission and retrieval) on web server.

用户可以离线提交表单(即,将数据存储到设备上的本地数据库).并且只要网络可用,后台服务就应该将这些数据提交给网络服务器.

User can submit forms offline (ie. storing data to local db on device). And whenever network is available, background service should submit those data to web server.

后台服务的详细需求如下:

The detail requirement of background service is like:

  • 后台服务会先检查网络是否可用
  • 如果网络可用,它将收集本地数据库中的数据存储(SQLite)在设备上
  • 将数据提交给服务器
  • 要求服务器有任何新数据,如果可用,获取该数据并更新设备上的本地数据库.

我对 iOS 和 xamarin/monotouch 很陌生,想知道如何实现这一点?

I am quite new to iOS and xamarin/monotouch, and would like to know how to achieve this?

我了解iOS中的各种后台模式,例如后台获取、nsurlsession、后台传输等

I know about various background modes in iOS, such as background fetch, nsurlsession, background transfer etc.

我已尝试实现我认为适合我的情况的后台提取.但它按自己的时间运行.

I have try to implement Background Fetch which i think is suitable for my situation. but it runs on it's own time.

还想知道,如果用户杀死了我的应用程序,那么后台提取也会调用并仍然运行我的应用程序?

Also would like to know that if user has killed my application, then also background fetch will invoke and still run my application ?

我的 appdelegate -> PerformFetch 方法中的代码是这样的:

the code is something like this in my appdelegate -> PerformFetch method:

if(networkService.IsNetworkAvailable())
{
   if(this.syncDataService.DownloadNewDataFromServer())
   {
       Console.WriteLine("Data downloaded successfully from server..");
   }
   if(this.syncDataService.UploadDataToServer())
   {
       Console.WriteLine("Data submitted successfully to server...");
   }
   completionHandler(UIBackgroundFetchResult.NewData);
}
else
{
   completionHandler(UIBackgroundFetchResult.NoData);
}

更新:最后我以这种方式实现了它(希望它可以对某人有所帮助):

Update: Finally I have implemented it like this way (hope it can be helpful for someone) :

public class LocationUpdatedEventArgs : EventArgs
{
    private CLLocation location;

    public LocationUpdatedEventArgs(CLLocation location)
    {
        this.location = location;
    }

    public CLLocation Location
    {
        get { return this.location; }
    }
}

public class LocationManager
    {
        private static DateTime lastServiceRun;

        private CLLocationManager locMgr;

        public LocationManager()
        {
            this.locMgr = new CLLocationManager();
            this.LocationUpdated += this.PrintLocation;
            this.locMgr.Failed += (object sender, NSErrorEventArgs e) =>
            {
                Console.WriteLine("didFailWithError " + e.Error);
                Console.WriteLine("didFailWithError coe " + e.Error.Code);
            };
        }


        public event EventHandler<LocationUpdatedEventArgs> LocationUpdated = delegate { };


        public static TimeSpan TimeDiff { get; set; }


        public CLLocationManager LocMgr
        {
            get
            {
                return this.locMgr;
            }
        }


        public void StartLocationUpdates()
        {

            if (CLLocationManager.LocationServicesEnabled)
            {
                // sets the accuracy that we want in meters
                this.LocMgr.DesiredAccuracy = 1;

                //// Location updates are handled differently pre-iOS 6. If we want to support older versions of iOS,
                //// we want to do perform this check and let our LocationManager know how to handle location updates.

                if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0))
                {
                    this.LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) =>
                    {
                        //// fire our custom Location Updated event
                        this.LocationUpdated(this, new LocationUpdatedEventArgs(e.Locations[e.Locations.Length - 1]));
                    };
                }
                else
                {
                    //// this won't be called on iOS 6 (deprecated). We will get a warning here when we build.
                    this.LocMgr.UpdatedLocation += (object sender, CLLocationUpdatedEventArgs e) =>
                    {
                        this.LocationUpdated(this, new LocationUpdatedEventArgs(e.NewLocation));
                    };
                }

                //// Start our location updates
                this.LocMgr.StartUpdatingLocation();

                lastServiceRun = DateTime.Now;

                // Get some output from our manager in case of failure
                this.LocMgr.Failed += (object sender, NSErrorEventArgs e) =>
                {
                    Console.WriteLine(e.Error);
                };
            }
            else
            {
                //// Let the user know that they need to enable LocationServices
                Console.WriteLine("Location services not enabled, please enable this in your Settings");
            }
        }

        /// <summary>
        /// The stop updating location.
        /// </summary>
        public void StopUpdatingLocation()
        {
            this.locMgr.StopUpdatingLocation();
        }

        /// <summary>
        /// The print location. (This will keep going in the background)
        /// </summary>
        /// <param name="sender"> The sender. </param>
        /// <param name="e"> Location updated event argument </param>
        public void PrintLocation(object sender, LocationUpdatedEventArgs e)
        {
            CLLocation location = e.Location;

            Console.WriteLine("Longitude: " + location.Coordinate.Longitude);
            Console.WriteLine("Latitude: " + location.Coordinate.Latitude);

            var diff = DateTime.Now - lastServiceRun;
            TimeDiff = diff;
            if (TimeDiff.Minutes == 2)
            {
        // RunInBackground() is my method which call the service to upload/download data from server
                if (this.RunInBackground())
                {
                    lastServiceRun = DateTime.Now;
                }
            }
        }
}

推荐答案

计时器永远不会在后台工作,并且您无法在此方法中添加其他线程.DidEnterBackground 用于完成待处理的任务.这通常会持续大约 30 秒 - 1 分钟.

The timer never works in background, and you cannot add another thread in this method. DidEnterBackground is used to complete pending tasks. This will usually last for approximately 30secs - 1 minute.

您可以在此方法中添加循环或添加长时间运行的任务.

You can add a loop or add a long running task in this method.

这篇关于如何在ios中永远运行后台服务以同步数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆