如何在ios中永远运行后台服务以同步数据

2024-03-27

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

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

后台服务具体需求如下:

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

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

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

我尝试实现后台获取,我认为它适合我的情况。但它按照自己的时间运行。

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

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

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:最后我是这样实现的(希望对某人有帮助):

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 分钟。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在ios中永远运行后台服务以同步数据 的相关文章

  • 如何反序列化 XML 文档

    如何反序列化此 XML 文档
  • 以编程方式更新 Wifi 网络

    我正在尝试创建一个程序 当某个 wifi 网络在范围内时 该程序会连接到该网络 即使已经连接到另一个 wifi 也是如此 我在用着简单Wifi https github com DigiExam simplewifi 基本上效果很好 除了在
  • 我应该使用字节还是int?

    我记得曾在某处读到 即使您只需要字节 使用 Int32 更好 就性能而言 它 据说 仅适用于您不关心存储的情况 这是有效的吗 例如 我需要一个保存一周中某一天的变量 我是吗 int dayOfWeek or byte dayOfWeek E
  • 如何为二进制格式化程序创建 SerializationBinder,以处理类型从一个程序集和命名空间到另一个程序集和命名空间的移动

    上下文如下 我想通过将代码移动到不同的项目来重构代码 其中一些代码包含可序列化的 DTO 用于 跨多个端点发送和接收数据 如果我移动代码 序列化就会中断 因此它不是 向后兼容我的应用程序的旧版本 这个问题的一个解决方案是 Serializa
  • 如何在 C++11 中返回类成员向量

    我读了几篇关于如何从方法返回向量的文章 其中包括 c11 右值和移动语义混淆返回语句 https stackoverflow com questions 4986673 c11 rvalues and move semantics conf
  • 我想找到 C# 代码中所有后面没有括号的 if 语句。通过正则表达式

    我想找到所有if声明和for后面没有大括号的语句 当你在一个文件中写入一行时if声明您大多不会将其括在大括号中 所以我想找到所有这些if and for声明 请帮忙 就像我想捕捉这个声明 if childNode Name B return
  • 批量插入,asp.net

    我需要获取与会员相对应的 ID 号列表 在任何给定时间处理的数量可能在 10 到 10 000 之间 我可以毫无问题地收集数据 解析数据并将其加载到 DataTable 或任何内容 C 中 但我想在数据库中执行一些操作 将所有这些数据插入表
  • 如何动态添加XCTestCase

    我正在为一个白标签项目编写 UI 测试 其中每个应用程序都有一组不同的菜单项 测试点击每个菜单项并截取屏幕截图 使用快车道快照 https docs fastlane tools actions snapshot 目前这一切都发生在一个内部
  • 如何通过分解 y 轴来减小 mschart 的高度

    如何降低 mschart 的高度 如下所示 编辑 就我而言 我不想查看中断图表 this chart1 ChartAreas 0 AxisY ScaleBreakStyle Enabled false 您似乎正在寻找AxisY ScaleB
  • 如何处理文件名中的空格

    我正在尝试迭代本地目录中的文件 foreach string name in Directory GetFileSystemEntries path FileAttrtibutes att File GetAttributes name 文
  • 括号内声明的对象的范围

    如果我声明一个这样的对象 void main myclass objectA anotherclass true true 0 即 我通过直接调用后者的构造函数来创建一个 objectA 和另一个对象 anotherclass anothe
  • Qt - 添加超链接到对话框

    有没有办法在 Qt 对话框中添加可点击的超链接 IE 它应该看起来像一个超链接 蓝色文本 当您单击它时 它应该在浏览器中打开该超链接 像这样的东西 Use QLabel setOpenExternalLinks bool 并在标签上设置文本
  • 警告:在 Visual Studio 2015 中创建跨平台 Xamarin 空白应用程序(Xamarin.Form 便携式)

    每当我尝试创建上述类型的新项目时 我都会收到以下 4 个警告 预更新 Nuget 1 Warning IDE0006 Error encountered while loading the project Some project feat
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu
  • iOS 上的推送通知渐进式 Web 应用程序

    我需要开发一个集成了推送通知的渐进式网络应用程序 在网上搜索我发现了关于这个主题的不同意见 如果我理解正确的话 目前我们无法在移动版 safari 中推送通知 但仅限桌面版 这样对吗 你有什么建议来获得相同的结果吗 我不是iOS专家 我想知
  • 使用属性和性能

    我正在优化我的代码 我注意到使用属性 甚至自动属性 对执行时间有深远的影响 请参阅下面的示例 Test public void GetterVsField PropertyTest propertyTest new PropertyTest
  • ios swift 如何将默认语言设置为阿拉伯语?

    我正在开发一个有两种语言的应用程序 即英语和阿拉伯语 我用英语编写了该应用程序 然后用阿拉伯语本地化了该应用程序 更改语言时需要重新启动应用程序 我唯一的问题是 第一次安装应用程序时如何将默认语言设置为阿拉伯语 我尝试在编辑方案部分将语言设
  • 为什么在一行中使用这个 C++ 函数两次会导致编译错误?

    我在尝试在 Visual C 2010 中实现智能相等测试宏类型模板函数时遇到了一些麻烦 该函数与VS 中关于模板函数默认参数的错误 https stackoverflow com questions 10343177 why do i g
  • Web 和 winforms 的 .Net 身份验证

    我有一个为客户端构建的 ASP NET Web 应用程序 它使用默认的 ASP NET 表单身份验证 他们现在请求一个能够 与 Web 应用程序一起工作的桌面 WinForms 应用程序 我已经创建了 Web 服务来访问他们想要从 Web
  • 在启动屏幕中执行代码已更新

    在原始启动屏幕中执行代码 https stackoverflow com questions 27642016 execute code in launch screen 现在默认的LaunchScreenXcode 项目中的文件已更改为

随机推荐