Register Login

Talwrn Technology Blog

Mar 17

Written by: S White
Wed, 17 Mar 2010 20:52:50 GMT 

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.

 

latest1 latest2 latest3
User taps the ‘Latest’ button Async call is made Latest view is shown

 

public class 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 viewwillappear
        public override void ViewWillAppear (bool animated)
        {                    
            progressIndicator = ProgressIndicator();
            progressIndicator.HidesWhenStopped = true;
            progressIndicator.StartAnimating();
            this.View.AddSubview(progressIndicator);
                
            UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
        }
        
        // make the async call in viewdidappear
        public override void ViewDidAppear(bool animated)
        {
            var service = new FishHere();
            service.GetLatestFisheriesCompleted += HandleServiceGetLatestFisheriesCompleted;
            service.GetLatestFisheriesAsync();
        }

        // handle the completed event and hide the progressIndicator
        void 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);
                }        
            });
        }
        
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();
            this.Title = "Latest";
        }
        
        private class TableViewDelegate : UITableViewDelegate
        {
            private LatestViewController _lvc;
            private List<Fishery> _fisheries;
            
            public TableViewDelegate(LatestViewController controller, List<Fishery> fisheries)
            {
                _lvc = controller;
                _fisheries = fisheries;
            }
            
            public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
            {
                Fishery f = _fisheries[indexPath.Row];
                LatestViewDetailsController latestDetailsView = new LatestViewDetailsController(f);
                latestDetailsView.Title = f.FisheryName;
                _lvc.NavigationController.PushViewController(latestDetailsView, true);    
            }
        }
        
        private class 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>();
            }
            
            public override int RowsInSection (UITableView tableView, int section)
            {
                return Fisheries.Count;
            }
            
            public override 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.

Tags:

1 comment(s) so far...

Re: MonoTouch – UITableView async web service with progress

I've surfed the net more than three hours today, and your blog was the coolest of all. Thanks a lot, it is really useful to me.

By POS on   Wed, 03 Nov 2010 09:45:28 GMT

Search

Blog

You must be logged in and have permission to create or edit a blog.

Blog Archive

Home · iPhone and Android Apps · Blog · Contact
Terms Of Use  ·  Privacy Statement  ·  Copyright 2013 by Talwrn Technology