Change to another ViewController Programmatically

In order for you to get to another screen, just simply use this code, Change MainDisplayViewController as needed to your View Controller

MainDisplayViewController mainDisplayViewController = this.Storyboard.InstantiateViewController("MainDisplayViewController") as MainDisplayViewController;
if (mainDisplayViewController != null)
{
    this.NavigationController.PushViewController(mainDisplayViewController, true);
}

MessageBox.Show() Method

I am a Windows Developer at heart.  I prefer to call a method that I created, though I should really learn the newer Xamarin methods and stick to those.  Here is my code:

private void MessageBox(string message, string title)
{
    UIAlertView alert = new UIAlertView();
    alert.Title = title;
    alert.AddButton("OK");
    alert.Message = message;
    //alert.AlertViewStyle = UIAlertViewStyle.SecureTextInput;
    alert.Show();
}

Keeping an App Alive while in the Background

Sometimes you will want to run an app in the background for good reason.  To do this, (and as far as I can tell) your only option to being able to do this will be to track the users location, even though you are not actually tracking the user, you need to keep their GPS on and running.  This is not always something people are willing to do though!

Take DropBox for example.  If you want the background sync to always be running, you will see a message that says something about keeping your apps running in the background.

2014-12-28_13-53-07

Now, if all you want to do is call a service to see if the user should receive some sort of notification, this is not for you.  In that case, you would want to do Push notifications, and doing that requires a server and is much harder to do.  I will show you how to do that in a few posts.

First, create the new project, in my case I called it LocalNotificationExample

2014-12-28_13-42-40

Next, in your info.plist file, you will need to set the Background Mode to True, then set your Location updates to True.

2014-12-28_14-21-42_01

Next, go to the Source tab, then add the following with the corresponding values.2014-12-28_14-23-49

In your View Controller the source should look like this:

using System;
using System.Drawing;

using Foundation;
using UIKit;

namespace LocalNotificationExample
{
    public partial class LocalNotificationExampleViewController : UIViewController
    {
        public static LocationManager Manager { get; set; }

        public LocalNotificationExampleViewController (IntPtr handle) : base (handle)
        {
            // As soon as the app is done launching, begin generating location updates in the location manager
            Manager = new LocationManager();
            Manager.StartLocationUpdates();
        }

        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();
            
            // Release any cached data, images, etc that aren't in use.
        }

        #region View lifecycle

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad();

            // Perform any additional setup after loading the view, typically from a nib.

            // Screen subscribes to the location changed event
            UIApplication.Notifications.ObserveDidBecomeActive((sender, args) =>
                {
                    Manager.LocationUpdated += HandleLocationChanged;
                });

            // Whenever the app enters the background state, we unsubscribe from the event 
            // so we no longer perform foreground updates
            UIApplication.Notifications.ObserveDidEnterBackground((sender, args) =>
                {
                    Manager.LocationUpdated -= HandleLocationChanged;
                });

            var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());
            UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
        }

        public override void ViewWillAppear (bool animated)
        {
            base.ViewWillAppear (animated);
        }

        public override void ViewDidAppear (bool animated)
        {
            base.ViewDidAppear (animated);
        }

        public override void ViewWillDisappear (bool animated)
        {
            base.ViewWillDisappear (animated);
        }

        public override void ViewDidDisappear (bool animated)
        {
            base.ViewDidDisappear (animated);
        }

        #endregion

        public void HandleLocationChanged(object sender, LocationUpdatedEventArgs e)
        {

        }
    }
}

You will need to add a class called LocationManager.cs and insert the following code:

using System;
using System.Drawing;
using System.Collections.Generic;

using Foundation;
using UIKit;
using CoreLocation;

namespace LocalNotificationExample
{
    public class LocationUpdatedEventArgs : EventArgs
    {
        CLLocation location;

        public LocationUpdatedEventArgs(CLLocation location)
        {
            this.location = location;
        }

        public CLLocation Location
        {
            get { return location; }
        }
    }
}

You will need to add a class called LocationUpdatedEventArgs.cs and insert the following code:

using System;
using System.Drawing;
using System.Collections.Generic;

using Foundation;
using UIKit;
using CoreLocation;

namespace LocalNotificationExample
{
    public class LocationManager
    {
    private List<string> LocationsReceived = new List<string>();

    // event for the location changing
    public event EventHandler<LocationUpdatedEventArgs> LocationUpdated = delegate { };

    public LocationManager()
    {
        this.locMgr = new CLLocationManager();
        LocationUpdated += PrintLocation;
    }

    // create a location manager to get system location updates to the application
    public CLLocationManager LocMgr
    {
        get
        {
            return this.locMgr;
        }
    } protected CLLocationManager locMgr;

    public void StartLocationUpdates()
    {
        // We need the user's permission for our app to use the GPS in iOS. This is done either by the user accepting
        // the popover when the app is first launched, or by changing the permissions for the app in Settings

        if (CLLocationManager.LocationServicesEnabled)
        {

            LocMgr.DesiredAccuracy = 1; // sets the accuracy that we want in meters

            // 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))
            {

                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.
                LocMgr.UpdatedLocation += (object sender, CLLocationUpdatedEventArgs e) =>
                {
                    this.LocationUpdated(this, new LocationUpdatedEventArgs(e.NewLocation));
                };
            }

            // Start our location updates
            LocMgr.StartUpdatingLocation();
            LocMgr.PausesLocationUpdatesAutomatically = false;

            // Get some output from our manager in case of failure
            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");

        }
    }

    //This will keep going in the background and the foreground
    public void PrintLocation(object sender, LocationUpdatedEventArgs e)
    {
        CLLocation location = e.Location;

        Console.WriteLine("Altitude: " + location.Altitude + " meters");
        Console.WriteLine("Longitude: " + location.Coordinate.Longitude);
        Console.WriteLine("Latitude: " + location.Coordinate.Latitude);
        Console.WriteLine("Course: " + location.Course);
        Console.WriteLine("Speed: " + location.Speed);

        
            SendNotification ("This is your notification!", "Local Notification");

    }

    private void SendNotification (string title, string message)
        {
            try {
                using (UILocalNotification notification = new UILocalNotification ()) {
                    notification.FireDate = (NSDate)DateTime.Now;
                    notification.AlertAction = title;
                    notification.AlertBody = message;
                    notification.SoundName = UILocalNotification.DefaultSoundName;

                    UIApplication.SharedApplication.ScheduleLocalNotification (notification);
                }
            } catch (Exception ex) {
                Console.WriteLine ("Error sending notification: " + ex.Message);
            }
        }

    }
}

When you load the app, you will get the following message:

IMG_0001

However, you will notice that you will not receive any notifications, and this is simply because your app needs to get access still to the GPS in your device.  So go to your Privacy settings, then choose Navigation.

IMG_0002

Once this is done, you will have to allow your app to use your location always.  Go back in to your app, and close it again (not terminating it), then you will start receiving notifications every second, you can replace this your normal processing…  But your app is now in the background!

IMG_0003

To se the full app, click here!