title: How to run background service in ios forever for syncing of data
body: <p>Hi I am developing an App which has a requirement to do syncing operation (data submission and retrieval) on web server. </p>
  
  <p>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.</p>
  
  <p>The detail requirement of background service is like:</p>
  
  <ul>
  <li>Background service will first check whether network is available or not</li>
  <li>if network is available, it will collect the data store in Local db (SQLite)
  on device </li>
  <li>It submit the data to server</li>
  <li>ask server to have any new    data, and if available, get that data
  and update the local database    on device.</li>
  </ul>
  
  <p>I am quite new to iOS and xamarin/monotouch, and would like to know how to achieve this?</p>
  
  <p>I know about various background modes in iOS, such as background fetch, nsurlsession, background transfer etc.</p>
  
  <p>I have try to implement Background Fetch which i think is suitable for my situation. but it runs on it's own time. </p>
  
  <p>Also would like to know that if user has killed my application, then also background fetch will invoke and still run my application ?</p>
  
  <p>the code is something like this in my appdelegate -> PerformFetch method:</p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p><strong>Update:</strong> Finally I have implemented it like this way (hope it can be helpful for someone) :</p>
  
  <pre><code>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) =&gt;
              {
                  Console.WriteLine("didFailWithError " + e.Error);
                  Console.WriteLine("didFailWithError coe " + e.Error.Code);
              };
          }
  
  
          public event EventHandler&lt;LocationUpdatedEventArgs&gt; 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) =&gt;
                      {
                          //// 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) =&gt;
                      {
                          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) =&gt;
                  {
                      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");
              }
          }
  
          /// &lt;summary&gt;
          /// The stop updating location.
          /// &lt;/summary&gt;
          public void StopUpdatingLocation()
          {
              this.locMgr.StopUpdatingLocation();
          }
  
          /// &lt;summary&gt;
          /// The print location. (This will keep going in the background)
          /// &lt;/summary&gt;
          /// &lt;param name="sender"&gt; The sender. &lt;/param&gt;
          /// &lt;param name="e"&gt; Location updated event argument &lt;/param&gt;
          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;
                  }
              }
          }
  }
  </code></pre>