您好,我正在开发一个应用程序,它需要在网络服务器上进行同步操作(数据提交和检索)。
用户可以离线提交表单(即将数据存储到设备上的本地数据库)。只要网络可用,后台服务就应该将这些数据提交到网络服务器。
后台服务具体需求如下:
- 后台服务会先检查网络是否可用
- 如果网络可用,它将收集本地数据库(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;
}
}
}
}