Wait for Data to Sync and Update UI


#1

I am just starting with Realm and I am writing a Xamarin application for Android that downloads a schedule for a driver. The app can’t display the schedule until the data has been synced from a partial Realm in ROS. I have tried using the example code in the documentation which successfully waits until the data has been synced however the data is not displayed in the UI - I presume this is because the the code is updating the data on a separate thread to the UI.

My code is as follows;

protected override async void OnAppearing()
{
	var config = ConnectionServices.GetRealmConfiguration("~/RunSheet", user);
	realm = ConnectionServices.ConnectToSyncServer(config);
	SynchroniseRealm(config);
}

private void SynchroniseRealm(FullSyncConfiguration config)
{
	// Wait until the session has determined the data to be synchronised
	var session = realm.GetSession();
	Thread.Sleep(250);

	var uploadProgress = session.GetProgressObservable(ProgressDirection.Upload, ProgressMode.ReportIndefinitely);
	var downloadProgress = session.GetProgressObservable(ProgressDirection.Download, ProgressMode.ReportIndefinitely);

	var token = uploadProgress.CombineLatest(downloadProgress, (upload, download) =>
		{
			return new
			{
				TotalTransferred = upload.TransferredBytes + download.TransferredBytes,
				TotalTransferable = upload.TransferableBytes + download.TransferableBytes
			};
		})
		.Throttle(TimeSpan.FromSeconds(0.1))
		.ObserveOn(SynchronizationContext.Current)
		.Subscribe(progress =>
		{
			if (progress.TotalTransferred < progress.TotalTransferable)
			{
				var downloaded = (int)((double)progress.TotalTransferred / (double)progress.TotalTransferable * 100);
				ReportProgress(downloaded);
			}
			else
			{
				DownloadComplete(config);
			}
		});
}

private async void DownloadComplete(FullSyncConfiguration config)
{
	var localRealm = ConnectionServices.ConnectToSyncServer(config);
	driver = GetDriver(localRealm, userName);
	driverRuns = driver.Runs.ToList();
	DisplayRun(DateTime.Today, localRealm);
}

private RealmSx.Models.Driver GetDriver(Realm realm, string driverName)
{
	var driverService = new DriverServices(realm);
	var driver = driverService.GetByName(driverName);
	return driver;
}

public Driver GetByName(string driverName)
{
	var results = realm.All<Driver>();
	return = results.FirstOrDefault(x => x.UserName == driverName);
}

private void DisplayRun(DateTime runDt, Realm localRealm)
{
	run = driverRuns.FirstOrDefault(x => x.RunStart.Date == runDt);

	// Add the jobs to the view model...
	Jobs = new List<ViewModels.JobVm>();

	foreach (var realmJob in run.Jobs)
	{
		if (realmJob.JobDate.ToLocalTime().Date == runDt.Date)
		{
			ViewModels.JobVm job = new ViewModels.JobVm(realmJob);

			job.DriverId = driver.Id;
			job.RunId = run.Id;
			.
			.
			.
			jobs.Add(job);
		}
	}

	Jobs = jobs;
}

#2

Found the problem - it had nothing to do with syncing or threading - there was an error in another part of the code.