It’s recommended that web service calls are made asynchronously to make the app more responsive. However, the user needs to know that something is happening during the call. The NetworkIndicator can be used for this but I wanted something more obvious.
 |  |  |
| User taps the ‘Latest’ button | Async call is made | Latest view is shown |
publicclass LatestViewController : UIViewController
{
private UIActivityIndicatorView progressIndicator;
private UITableView tableView;
private List<Fishery> Fisheries;
private UIActivityIndicatorView ProgressIndicator ()
{
UIActivityIndicatorView pind = new UIActivityIndicatorView (new RectangleF(145f, 165f, 30f, 30f)){
ActivityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray,
AutoresizingMask = UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleTopMargin | UIViewAutoresizing.FlexibleBottomMargin,
Tag = 1
};
return pind;
}
// show the progressIndicator in viewwillappearpublicoverridevoid ViewWillAppear (bool animated)
{
progressIndicator = ProgressIndicator();
progressIndicator.HidesWhenStopped = true;
progressIndicator.StartAnimating();
this.View.AddSubview(progressIndicator);
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
}
// make the async call in viewdidappearpublicoverridevoid ViewDidAppear(bool animated)
{
var service = new FishHere();
service.GetLatestFisheriesCompleted += HandleServiceGetLatestFisheriesCompleted;
service.GetLatestFisheriesAsync();
}
// handle the completed event and hide the progressIndicatorvoid HandleServiceGetLatestFisheriesCompleted (object sender, GetLatestFisheriesCompletedEventArgs args)
{
// Since the asych call runs on a separate thread,// we can't access UIKit obects from there, so we// invoke those on the main thread
InvokeOnMainThread (delegate {
progressIndicator.StopAnimating();
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
Fisheries = new List<Fishery>();
System.Xml.XmlNode result = (System.Xml.XmlNode)args.Result;
XDocument feed = XDocument.Parse(result.OuterXml);
var query = from item in feed.Descendants("fishery") select new Fishery
{
FisheryId = (string) item.Element("itemid"),
FisheryName = (string) item.Element("itemname"),
FisheryDescription = (string) item.Element("itemdesc"),
CountyName = (string) item.Element("countyname"),
CategoryName = (string) item.Element("categoryname"),
FisheryAddress = (string) item.Element("itemaddress"),
FisheryPostcode = (string) item.Element("postcode"),
FisheryEmail = (string) item.Element("itememail"),
FisheryUrl = (string) item.Element("itemurl"),
FisheryLat = (string) item.Element("latitude"),
FisheryLng = (string) item.Element("longitude"),
ParentCategoryID = (string) item.Element("parentcategoryid")
};
Fisheries = query.ToList();
if (Fisheries.Count > 0)
{
tableView = new UITableView()
{
Delegate = new TableViewDelegate(this, Fisheries),
DataSource = new TableViewDataSource(Fisheries),
AutoresizingMask = UIViewAutoresizing.FlexibleHeight|UIViewAutoresizing.FlexibleWidth,
BackgroundColor = UIColor.GroupTableViewBackgroundColor,
};
tableView.SizeToFit();
tableView.Frame = new System.Drawing.RectangleF (0, 0, this.View.Frame.Width, this.View.Frame.Height);
this.View.AddSubview(tableView);
}
else
{
// add the view for the controls
UIView noResultView = new UIView();
noResultView.BackgroundColor = UIColor.Clear;
noResultView.SizeToFit();
noResultView.Frame = new System.Drawing.RectangleF(0, 0, this.View.Frame.Width, this.View.Frame.Height);
// add the main image
UIImageView noResultsScreen = new UIImageView(new System.Drawing.RectangleF(0, 0, 320, 375));
noResultsScreen.Image = UIImage.FromFile("images/home_back.png");
noResultsScreen.Frame = new System.Drawing.RectangleF(0, 0, 320, 375);
noResultView.AddSubview(noResultsScreen);
// Add the no results label
UITextView noResultsView = new UITextView(new System.Drawing.RectangleF(0, 0, 320, 200));
noResultsView.Editable = false;
noResultsView.TextAlignment = UITextAlignment.Center;
noResultsView.BackgroundColor = UIColor.Clear;
noResultsView.TextColor = UIColor.White;
noResultsView.Font = UIFont.FromName("Helvetica", 18);
noResultsView.ScrollEnabled = false;
noResultsView.Text = "No Fisheries found";
noResultView.AddSubview(noResultsView);
this.View.AddSubview(noResultView);
}
});
}
publicoverridevoid ViewDidLoad ()
{
base.ViewDidLoad ();
this.Title = "Latest";
}
privateclass TableViewDelegate : UITableViewDelegate
{
private LatestViewController _lvc;
private List<Fishery> _fisheries;
public TableViewDelegate(LatestViewController controller, List<Fishery> fisheries)
{
_lvc = controller;
_fisheries = fisheries;
}
publicoverridevoid RowSelected (UITableView tableView, NSIndexPath indexPath)
{
Fishery f = _fisheries[indexPath.Row];
LatestViewDetailsController latestDetailsView = new LatestViewDetailsController(f);
latestDetailsView.Title = f.FisheryName;
_lvc.NavigationController.PushViewController(latestDetailsView, true);
}
}
privateclass TableViewDataSource : UITableViewDataSource
{
static NSString kCellIdentifier = new NSString("MyIdentifier");
private List<Fishery> Fisheries;
private Dictionary<int, FisheryCellController> controllers = null;
public TableViewDataSource (List<Fishery> Fisheries)
{
this.Fisheries = Fisheries;
controllers = new Dictionary<int, FisheryCellController>();
}
publicoverrideint RowsInSection (UITableView tableView, int section)
{
return Fisheries.Count;
}
publicoverride UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell (kCellIdentifier);
FisheryCellController cellController = null;
if (cell == null)
{
cellController = new FisheryCellController();
NSBundle.MainBundle.LoadNib("FisheryCellController", cellController, null);
cell = cellController.Cell;
cell.Tag = Environment.TickCount;
controllers.Add(cell.Tag, cellController);
}
else
{
cellController = controllers[cell.Tag];
}
Fishery fishery = Fisheries.ElementAt(indexPath.Row);
cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
cellController.Name = fishery.FisheryName;
cellController.County = fishery.CountyName;
cellController.CategoryImageView.Image = UIImage.FromFile("images/icon_fishery40x40.png");
return cell;
}
}
}Big thanks to Craig’s blog for lots of things in here.