From d75b9c3f64f03d99103126c1d9c3b65fd94677ca Mon Sep 17 00:00:00 2001 From: Oleg Demchenko Date: Thu, 10 Sep 2015 11:37:25 -0300 Subject: [PATCH] [Reachability] Fix startup crash + update sample --- ReachabilitySample/AppDelegate.cs | 170 +---------- ReachabilitySample/Info.plist | 2 + ReachabilitySample/Main.cs | 14 + ReachabilitySample/Main.storyboard | 57 ++++ ReachabilitySample/MainViewController.cs | 135 +++++++++ .../MainViewController.designer.cs | 20 ++ ReachabilitySample/MainWindow.xib | 276 ----------------- ReachabilitySample/MainWindow.xib.designer.cs | 60 ---- ReachabilitySample/Reachability.cs | 143 +++++++++ ReachabilitySample/reachability.cs | 285 +++++++++--------- ReachabilitySample/reachability.csproj | 41 +-- ReachabilitySample/reachability.sln | 5 +- 12 files changed, 535 insertions(+), 673 deletions(-) create mode 100644 ReachabilitySample/Main.cs create mode 100644 ReachabilitySample/Main.storyboard create mode 100644 ReachabilitySample/MainViewController.cs create mode 100644 ReachabilitySample/MainViewController.designer.cs delete mode 100644 ReachabilitySample/MainWindow.xib delete mode 100644 ReachabilitySample/MainWindow.xib.designer.cs create mode 100644 ReachabilitySample/Reachability.cs diff --git a/ReachabilitySample/AppDelegate.cs b/ReachabilitySample/AppDelegate.cs index e8acbdb1..9051908e 100644 --- a/ReachabilitySample/AppDelegate.cs +++ b/ReachabilitySample/AppDelegate.cs @@ -1,170 +1,10 @@ -using System; -using CoreGraphics; -using Foundation; +using Foundation; using UIKit; -namespace reachability -{ - public partial class ReachabilityAppDelegate : UIApplicationDelegate - { - UITableView tableView; - NetworkStatus remoteHostStatus, internetStatus, localWifiStatus; - - static void Main (string[] args) - { - UIApplication.Main (args, null, (string)null); - } - - public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) - { - AddTable (); - UpdateStatus (); - Reachability.ReachabilityChanged += (object sender, EventArgs e) => { - UpdateStatus (); - }; - - window.MakeKeyAndVisible (); - - return true; - } - - void UpdateStatus () - { - remoteHostStatus = Reachability.RemoteHostStatus (); - internetStatus = Reachability.InternetConnectionStatus (); - localWifiStatus = Reachability.LocalWifiConnectionStatus (); - tableView.ReloadData (); - } - - void AddTable () - { - CGRect tableFrame = UIScreen.MainScreen.ApplicationFrame; - - tableView = new UITableView (tableFrame, UITableViewStyle.Grouped) { - AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight, - RowHeight = 44.0f, - SeparatorStyle = UITableViewCellSeparatorStyle.None, - SectionHeaderHeight = 28.0f, - ScrollEnabled = false, - - Source = new DataSource (this), - }; - - contentView.InsertSubviewBelow (tableView, summaryLabel); - contentView.BringSubviewToFront (summaryLabel); - tableView.ReloadData (); - } - - class DataSource : UITableViewSource - { - ReachabilityAppDelegate parent; - UIImage imageCarrier, imageWiFi, imageStop; - - public DataSource (ReachabilityAppDelegate parent) - { - imageCarrier = UIImage.FromFile ("WWAN5.png"); - imageWiFi = UIImage.FromFile ("Airport.png"); - imageStop = UIImage.FromFile ("stop-32.png"); - - this.parent = parent; - } - - public override NSIndexPath WillSelectRow (UITableView view, NSIndexPath index) - { - return null; - } - - public override nint RowsInSection (UITableView view, nint section) - { - return 1; - } - - public override nint NumberOfSections (UITableView view) - { - return 3; - } - - public override string TitleForHeader (UITableView view, nint section) - { - switch (section) { - case 0: - return Reachability.HostName; - case 1: - return "Access to internet hosts"; - case 2: - return "Access to Local Bonjour Hosts"; - default: - return "Unknown"; - } - } - - static NSString ReachabilityTableCellIdentifier = new NSString ("ReachabilityTableCell"); - - public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) - { - var cell = tableView.DequeueReusableCell (ReachabilityTableCellIdentifier); - if (cell == null) { - cell = new UITableViewCell (UITableViewCellStyle.Default, ReachabilityTableCellIdentifier); - var label = cell.TextLabel; - label.Font = UIFont.SystemFontOfSize (12f); - label.TextColor = UIColor.DarkGray; - label.TextAlignment = UITextAlignment.Left; - } - - var row = indexPath.Row; - string text = ""; - UIImage image = null; - switch (indexPath.Section) { - case 0: - switch (parent.remoteHostStatus) { - case NetworkStatus.NotReachable: - text = "Cannot connect to remote host"; - image = imageStop; - break; - case NetworkStatus.ReachableViaCarrierDataNetwork: - text = "Reachable via data carrier network"; - image = imageCarrier; - break; - case NetworkStatus.ReachableViaWiFiNetwork: - text = "Reachable via WiFi network"; - image = imageWiFi; - break; - } - break; - case 1: - switch (parent.internetStatus) { - case NetworkStatus.NotReachable: - text = "Access not available"; - image = imageStop; - break; - case NetworkStatus.ReachableViaCarrierDataNetwork: - text = "Available via data carrier network"; - image = imageCarrier; - break; - case NetworkStatus.ReachableViaWiFiNetwork: - text = "Available via WiFi network"; - image = imageWiFi; - break; - } - break; - case 2: - switch (parent.localWifiStatus) { - case NetworkStatus.NotReachable: - text = "Access not available"; - image = imageStop; - break; - case NetworkStatus.ReachableViaWiFiNetwork: - text = "Available via WiFi network"; - image = imageWiFi; - break; - } - break; - } - cell.TextLabel.Text = text; - cell.ImageView.Image = image; - return cell; - } - } +namespace Reachability { + [Register ("AppDelegate")] + public class AppDelegate : UIApplicationDelegate { + public override UIWindow Window { get; set; } } } diff --git a/ReachabilitySample/Info.plist b/ReachabilitySample/Info.plist index 3ec8962a..d439a51f 100644 --- a/ReachabilitySample/Info.plist +++ b/ReachabilitySample/Info.plist @@ -29,5 +29,7 @@ UIInterfaceOrientationPortrait + UIMainStoryboardFile + Main diff --git a/ReachabilitySample/Main.cs b/ReachabilitySample/Main.cs new file mode 100644 index 00000000..3d60d50b --- /dev/null +++ b/ReachabilitySample/Main.cs @@ -0,0 +1,14 @@ +using UIKit; + +namespace Reachability { + public class Application { + // This is the main entry point of the application. + static void Main (string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main (args, null, "AppDelegate"); + } + } +} + diff --git a/ReachabilitySample/Main.storyboard b/ReachabilitySample/Main.storyboard new file mode 100644 index 00000000..9cb52678 --- /dev/null +++ b/ReachabilitySample/Main.storyboard @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ReachabilitySample/MainViewController.cs b/ReachabilitySample/MainViewController.cs new file mode 100644 index 00000000..d221d7a0 --- /dev/null +++ b/ReachabilitySample/MainViewController.cs @@ -0,0 +1,135 @@ +using System; + +using UIKit; +using Foundation; + +namespace Reachability { + public partial class MainViewController : UITableViewController { + const string ReachabilityTableCellIdentifier = "ReachabilityTableCell"; + + UIImage imageCarrier, imageWiFi, imageStop; + NetworkStatus remoteHostStatus, internetStatus, localWifiStatus; + + public MainViewController (IntPtr handle) : base (handle) + { + } + + public override void ViewDidLoad () + { + base.ViewDidLoad (); + UpdateStatus (null, null); + Reachability.ReachabilityChanged += UpdateStatus; + + imageCarrier = UIImage.FromFile ("WWAN5.png"); + imageWiFi = UIImage.FromFile ("Airport.png"); + imageStop = UIImage.FromFile ("stop-32.png"); + + TableView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; + TableView.RowHeight = 44.0f; + TableView.SeparatorStyle = UITableViewCellSeparatorStyle.None; + TableView.SectionHeaderHeight = 28.0f; + TableView.ScrollEnabled = false; + } + + public override NSIndexPath WillSelectRow (UITableView view, NSIndexPath index) + { + return null; + } + + public override nint RowsInSection (UITableView view, nint section) + { + return 1; + } + + public override nint NumberOfSections (UITableView view) + { + return 3; + } + + public override string TitleForHeader (UITableView view, nint section) + { + switch (section) { + case 0: + return Reachability.HostName; + case 1: + return "Access to internet hosts"; + case 2: + return "Access to Local Bonjour Hosts"; + default: + return "Unknown"; + } + } + + public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath) + { + var cell = tableView.DequeueReusableCell (ReachabilityTableCellIdentifier); + if (cell == null) { + cell = new UITableViewCell (UITableViewCellStyle.Default, ReachabilityTableCellIdentifier); + var label = cell.TextLabel; + label.Font = UIFont.SystemFontOfSize (12f); + label.TextColor = UIColor.DarkGray; + label.TextAlignment = UITextAlignment.Left; + } + + string text = ""; + UIImage image = null; + switch (indexPath.Section) { + case 0: + switch (remoteHostStatus) { + case NetworkStatus.NotReachable: + text = "Cannot connect to remote host"; + image = imageStop; + break; + case NetworkStatus.ReachableViaCarrierDataNetwork: + text = "Reachable via data carrier network"; + image = imageCarrier; + break; + case NetworkStatus.ReachableViaWiFiNetwork: + text = "Reachable via WiFi network"; + image = imageWiFi; + break; + } + break; + case 1: + switch (internetStatus) { + case NetworkStatus.NotReachable: + text = "Access not available"; + image = imageStop; + break; + case NetworkStatus.ReachableViaCarrierDataNetwork: + text = "Available via data carrier network"; + image = imageCarrier; + break; + case NetworkStatus.ReachableViaWiFiNetwork: + text = "Available via WiFi network"; + image = imageWiFi; + break; + } + break; + case 2: + switch (localWifiStatus) { + case NetworkStatus.NotReachable: + text = "Access not available"; + image = imageStop; + break; + case NetworkStatus.ReachableViaWiFiNetwork: + text = "Available via WiFi network"; + image = imageWiFi; + break; + } + break; + } + cell.TextLabel.Text = text; + cell.ImageView.Image = image; + return cell; + } + + void UpdateStatus (object sender, EventArgs e) + { + remoteHostStatus = Reachability.RemoteHostStatus (); + internetStatus = Reachability.InternetConnectionStatus (); + localWifiStatus = Reachability.LocalWifiConnectionStatus (); + TableView.ReloadData (); + } + } +} diff --git a/ReachabilitySample/MainViewController.designer.cs b/ReachabilitySample/MainViewController.designer.cs new file mode 100644 index 00000000..25479f74 --- /dev/null +++ b/ReachabilitySample/MainViewController.designer.cs @@ -0,0 +1,20 @@ +// WARNING +// +// This file has been generated automatically by Xamarin Studio to store outlets and +// actions made in the UI designer. If it is removed, they will be lost. +// Manual changes to this file may not be handled correctly. +// +using Foundation; +using System.CodeDom.Compiler; + +namespace Reachability +{ + [Register ("MainViewController")] + partial class MainViewController + { + + void ReleaseDesignerOutlets () + { + } + } +} diff --git a/ReachabilitySample/MainWindow.xib b/ReachabilitySample/MainWindow.xib deleted file mode 100644 index 4d7b7a66..00000000 --- a/ReachabilitySample/MainWindow.xib +++ /dev/null @@ -1,276 +0,0 @@ - - - - 512 - 10B504 - 740 - 1038.22 - 457.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 62 - - - YES - - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - YES - - - - YES - - IBFilesOwner - - - IBFirstResponder - - - - - 1292 - - YES - - - 1298 - - YES - - - 1306 - {{0, 318}, {320, 106}} - - NO - YES - NO - - - 1 - MSAwIDAAA - - - 1 - NO - 14 - 0 - 1 - - - {320, 480} - - - 3 - MQA - - 2 - - - NO - NO - - - - {320, 480} - - - 1 - MSAxIDEAA - - NO - NO - - - - - YES - - - delegate - - - - 5 - - - - window - - - - 6 - - - - contentView - - - - 8 - - - - summaryLabel - - - - 10 - - - - - YES - - 0 - - - - - - 2 - - - YES - - - - - - -1 - - - File's Owner - - - 4 - - - ReachabilityAppDelegate - - - 7 - - - YES - - - - - - 9 - - - - - -2 - - - - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 2.IBAttributePlaceholdersKey - 2.IBEditorWindowLastContentRect - 2.IBPluginDependency - 2.UIWindow.visibleAtLaunch - 4.CustomClassName - 4.IBPluginDependency - 7.IBPluginDependency - 9.IBPluginDependency - - - YES - UIApplication - UIResponder - - YES - - - YES - - - {{363, 365}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - ReachabilityAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 10 - - - - YES - - ReachabilityAppDelegate - NSObject - - YES - - YES - contentView - summaryLabel - window - - - YES - UIView - UILabel - UIWindow - - - - IBProjectSource - Classes/ReachabilityAppDelegate.h - - - - - 0 - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - Reachability.xcodeproj - 3 - 3.1 - - diff --git a/ReachabilitySample/MainWindow.xib.designer.cs b/ReachabilitySample/MainWindow.xib.designer.cs deleted file mode 100644 index 55244ba2..00000000 --- a/ReachabilitySample/MainWindow.xib.designer.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Mono Runtime Version: 4.0.30319.1 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ - -namespace reachability { - - // Base type probably should be MonoTouch.Foundation.NSObject or subclass - [Foundation.Register("ReachabilityAppDelegate")] - public partial class ReachabilityAppDelegate { - - private UIKit.UIWindow __mt_window; - - private UIKit.UIView __mt_contentView; - - private UIKit.UILabel __mt_summaryLabel; - - #pragma warning disable 0169 - [Foundation.Connect("window")] - private UIKit.UIWindow window { - get { - this.__mt_window = ((UIKit.UIWindow)(this.GetNativeField("window"))); - return this.__mt_window; - } - set { - this.__mt_window = value; - this.SetNativeField("window", value); - } - } - - [Foundation.Connect("contentView")] - private UIKit.UIView contentView { - get { - this.__mt_contentView = ((UIKit.UIView)(this.GetNativeField("contentView"))); - return this.__mt_contentView; - } - set { - this.__mt_contentView = value; - this.SetNativeField("contentView", value); - } - } - - [Foundation.Connect("summaryLabel")] - private UIKit.UILabel summaryLabel { - get { - this.__mt_summaryLabel = ((UIKit.UILabel)(this.GetNativeField("summaryLabel"))); - return this.__mt_summaryLabel; - } - set { - this.__mt_summaryLabel = value; - this.SetNativeField("summaryLabel", value); - } - } - } -} diff --git a/ReachabilitySample/Reachability.cs b/ReachabilitySample/Reachability.cs new file mode 100644 index 00000000..dd90e100 --- /dev/null +++ b/ReachabilitySample/Reachability.cs @@ -0,0 +1,143 @@ +using System; +using System.Net; +using SystemConfiguration; + +using CoreFoundation; + +namespace Reachability { + public enum NetworkStatus { + NotReachable, + ReachableViaCarrierDataNetwork, + ReachableViaWiFiNetwork + } + + public static class Reachability + { + public static string HostName = "www.google.com"; + + public static bool IsReachableWithoutRequiringConnection (NetworkReachabilityFlags flags) + { + // Is it reachable with the current network configuration? + bool isReachable = (flags & NetworkReachabilityFlags.Reachable) != 0; + + // Do we need a connection to reach it? + bool noConnectionRequired = (flags & NetworkReachabilityFlags.ConnectionRequired) == 0 + || (flags & NetworkReachabilityFlags.IsWWAN) != 0; + + return isReachable && noConnectionRequired; + } + + // Is the host reachable with the current network configuration + public static bool IsHostReachable(string host) + { + if (string.IsNullOrEmpty(host)) + return false; + + using (var r = new NetworkReachability(host)) { + NetworkReachabilityFlags flags; + + if (r.TryGetFlags(out flags)) + return IsReachableWithoutRequiringConnection(flags); + } + return false; + } + + // + // Raised every time there is an interesting reachable event, + // we do not even pass the info as to what changed, and + // we lump all three status we probe into one + // + public static event EventHandler ReachabilityChanged; + + static void OnChange(NetworkReachabilityFlags flags) + { + var h = ReachabilityChanged; + if (h != null) + h(null, EventArgs.Empty); + } + + // + // Returns true if it is possible to reach the AdHoc WiFi network + // and optionally provides extra network reachability flags as the + // out parameter + // + static NetworkReachability adHocWiFiNetworkReachability; + + public static bool IsAdHocWiFiNetworkAvailable (out NetworkReachabilityFlags flags) + { + if (adHocWiFiNetworkReachability == null) { + adHocWiFiNetworkReachability = new NetworkReachability(new IPAddress(new byte [] { 169, 254, 0, 0 })); + adHocWiFiNetworkReachability.SetNotification(OnChange); + adHocWiFiNetworkReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); + } + + return adHocWiFiNetworkReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); + } + + static NetworkReachability defaultRouteReachability; + + static bool IsNetworkAvailable(out NetworkReachabilityFlags flags) + { + if (defaultRouteReachability == null) { + defaultRouteReachability = new NetworkReachability(new IPAddress(0)); + defaultRouteReachability.SetNotification(OnChange); + defaultRouteReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); + } + return defaultRouteReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); + } + + static NetworkReachability remoteHostReachability; + + public static NetworkStatus RemoteHostStatus() + { + NetworkReachabilityFlags flags; + bool reachable; + + if (remoteHostReachability == null) { + remoteHostReachability = new NetworkReachability (HostName); + + // Need to probe before we queue, or we wont get any meaningful values + // this only happens when you create NetworkReachability from a hostname + reachable = remoteHostReachability.TryGetFlags (out flags); + + remoteHostReachability.SetNotification (OnChange); + remoteHostReachability.Schedule (CFRunLoop.Current, CFRunLoop.ModeDefault); + } else { + reachable = remoteHostReachability.TryGetFlags (out flags); + } + + if (!reachable) + return NetworkStatus.NotReachable; + + if (!IsReachableWithoutRequiringConnection(flags)) + return NetworkStatus.NotReachable; + + return (flags & NetworkReachabilityFlags.IsWWAN) != 0 ? + NetworkStatus.ReachableViaCarrierDataNetwork : NetworkStatus.ReachableViaWiFiNetwork; + } + + public static NetworkStatus InternetConnectionStatus () + { + NetworkReachabilityFlags flags; + bool defaultNetworkAvailable = IsNetworkAvailable(out flags); + if (defaultNetworkAvailable && ((flags & NetworkReachabilityFlags.IsDirect) != 0)) + return NetworkStatus.NotReachable; + else if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) + return NetworkStatus.ReachableViaCarrierDataNetwork; + else if (flags == 0) + return NetworkStatus.NotReachable; + return NetworkStatus.ReachableViaWiFiNetwork; + } + + public static NetworkStatus LocalWifiConnectionStatus() + { + NetworkReachabilityFlags flags; + if (IsAdHocWiFiNetworkAvailable(out flags)) + if ((flags & NetworkReachabilityFlags.IsDirect) != 0) + return NetworkStatus.ReachableViaWiFiNetwork; + + return NetworkStatus.NotReachable; + } + } +} + diff --git a/ReachabilitySample/reachability.cs b/ReachabilitySample/reachability.cs index 3b517715..dd90e100 100644 --- a/ReachabilitySample/reachability.cs +++ b/ReachabilitySample/reachability.cs @@ -1,156 +1,143 @@ using System; using System.Net; using SystemConfiguration; + using CoreFoundation; -public enum NetworkStatus -{ - NotReachable, - ReachableViaCarrierDataNetwork, - ReachableViaWiFiNetwork -} - -public static class Reachability -{ - public static string HostName = "www.google.com"; - - public static bool IsReachableWithoutRequiringConnection(NetworkReachabilityFlags flags) - { - // Is it reachable with the current network configuration? - bool isReachable = (flags & NetworkReachabilityFlags.Reachable) != 0; - - // Do we need a connection to reach it? - bool noConnectionRequired = (flags & NetworkReachabilityFlags.ConnectionRequired) == 0; - - // Since the network stack will automatically try to get the WAN up, - // probe that - if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) - noConnectionRequired = true; - - return isReachable && noConnectionRequired; - } - - // Is the host reachable with the current network configuration - public static bool IsHostReachable(string host) - { - if (string.IsNullOrEmpty(host)) - return false; - - using (var r = new NetworkReachability(host)) - { - NetworkReachabilityFlags flags; - - if (r.TryGetFlags(out flags)) - { - return IsReachableWithoutRequiringConnection(flags); - } - } - return false; - } - - // - // Raised every time there is an interesting reachable event, - // we do not even pass the info as to what changed, and - // we lump all three status we probe into one - // - public static event EventHandler ReachabilityChanged; - - static void OnChange(NetworkReachabilityFlags flags) - { - var h = ReachabilityChanged; - if (h != null) - h(null, EventArgs.Empty); - } - - // - // Returns true if it is possible to reach the AdHoc WiFi network - // and optionally provides extra network reachability flags as the - // out parameter - // - static NetworkReachability adHocWiFiNetworkReachability; - - public static bool IsAdHocWiFiNetworkAvailable(out NetworkReachabilityFlags flags) - { - if (adHocWiFiNetworkReachability == null) - { - adHocWiFiNetworkReachability = new NetworkReachability(new IPAddress(new byte [] { 169, 254, 0, 0 })); - adHocWiFiNetworkReachability.SetNotification(OnChange); - adHocWiFiNetworkReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); - } - - return adHocWiFiNetworkReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); - } - - static NetworkReachability defaultRouteReachability; - - static bool IsNetworkAvailable(out NetworkReachabilityFlags flags) - { - if (defaultRouteReachability == null) - { - defaultRouteReachability = new NetworkReachability(new IPAddress(0)); - defaultRouteReachability.SetNotification(OnChange); - defaultRouteReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); - } - return defaultRouteReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); - } - - static NetworkReachability remoteHostReachability; - - public static NetworkStatus RemoteHostStatus() - { - NetworkReachabilityFlags flags; - bool reachable; - - if (remoteHostReachability == null) - { - remoteHostReachability = new NetworkReachability(HostName); - - // Need to probe before we queue, or we wont get any meaningful values - // this only happens when you create NetworkReachability from a hostname - reachable = remoteHostReachability.TryGetFlags(out flags); - - remoteHostReachability.SetNotification(OnChange); - remoteHostReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); - } - else - reachable = remoteHostReachability.TryGetFlags(out flags); - - if (!reachable) - return NetworkStatus.NotReachable; - - if (!IsReachableWithoutRequiringConnection(flags)) - return NetworkStatus.NotReachable; - - if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) - return NetworkStatus.ReachableViaCarrierDataNetwork; - - return NetworkStatus.ReachableViaWiFiNetwork; - } - - public static NetworkStatus InternetConnectionStatus() - { - NetworkReachabilityFlags flags; - bool defaultNetworkAvailable = IsNetworkAvailable(out flags); - if (defaultNetworkAvailable && ((flags & NetworkReachabilityFlags.IsDirect) != 0)) - { - return NetworkStatus.NotReachable; - } - else if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) - return NetworkStatus.ReachableViaCarrierDataNetwork; - else if (flags == 0) - return NetworkStatus.NotReachable; - return NetworkStatus.ReachableViaWiFiNetwork; - } - - public static NetworkStatus LocalWifiConnectionStatus() - { - NetworkReachabilityFlags flags; - if (IsAdHocWiFiNetworkAvailable(out flags)) - { - if ((flags & NetworkReachabilityFlags.IsDirect) != 0) - return NetworkStatus.ReachableViaWiFiNetwork; - } - return NetworkStatus.NotReachable; - } +namespace Reachability { + public enum NetworkStatus { + NotReachable, + ReachableViaCarrierDataNetwork, + ReachableViaWiFiNetwork + } + + public static class Reachability + { + public static string HostName = "www.google.com"; + + public static bool IsReachableWithoutRequiringConnection (NetworkReachabilityFlags flags) + { + // Is it reachable with the current network configuration? + bool isReachable = (flags & NetworkReachabilityFlags.Reachable) != 0; + + // Do we need a connection to reach it? + bool noConnectionRequired = (flags & NetworkReachabilityFlags.ConnectionRequired) == 0 + || (flags & NetworkReachabilityFlags.IsWWAN) != 0; + + return isReachable && noConnectionRequired; + } + + // Is the host reachable with the current network configuration + public static bool IsHostReachable(string host) + { + if (string.IsNullOrEmpty(host)) + return false; + + using (var r = new NetworkReachability(host)) { + NetworkReachabilityFlags flags; + + if (r.TryGetFlags(out flags)) + return IsReachableWithoutRequiringConnection(flags); + } + return false; + } + + // + // Raised every time there is an interesting reachable event, + // we do not even pass the info as to what changed, and + // we lump all three status we probe into one + // + public static event EventHandler ReachabilityChanged; + + static void OnChange(NetworkReachabilityFlags flags) + { + var h = ReachabilityChanged; + if (h != null) + h(null, EventArgs.Empty); + } + + // + // Returns true if it is possible to reach the AdHoc WiFi network + // and optionally provides extra network reachability flags as the + // out parameter + // + static NetworkReachability adHocWiFiNetworkReachability; + + public static bool IsAdHocWiFiNetworkAvailable (out NetworkReachabilityFlags flags) + { + if (adHocWiFiNetworkReachability == null) { + adHocWiFiNetworkReachability = new NetworkReachability(new IPAddress(new byte [] { 169, 254, 0, 0 })); + adHocWiFiNetworkReachability.SetNotification(OnChange); + adHocWiFiNetworkReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); + } + + return adHocWiFiNetworkReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); + } + + static NetworkReachability defaultRouteReachability; + + static bool IsNetworkAvailable(out NetworkReachabilityFlags flags) + { + if (defaultRouteReachability == null) { + defaultRouteReachability = new NetworkReachability(new IPAddress(0)); + defaultRouteReachability.SetNotification(OnChange); + defaultRouteReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); + } + return defaultRouteReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); + } + + static NetworkReachability remoteHostReachability; + + public static NetworkStatus RemoteHostStatus() + { + NetworkReachabilityFlags flags; + bool reachable; + + if (remoteHostReachability == null) { + remoteHostReachability = new NetworkReachability (HostName); + + // Need to probe before we queue, or we wont get any meaningful values + // this only happens when you create NetworkReachability from a hostname + reachable = remoteHostReachability.TryGetFlags (out flags); + + remoteHostReachability.SetNotification (OnChange); + remoteHostReachability.Schedule (CFRunLoop.Current, CFRunLoop.ModeDefault); + } else { + reachable = remoteHostReachability.TryGetFlags (out flags); + } + + if (!reachable) + return NetworkStatus.NotReachable; + + if (!IsReachableWithoutRequiringConnection(flags)) + return NetworkStatus.NotReachable; + + return (flags & NetworkReachabilityFlags.IsWWAN) != 0 ? + NetworkStatus.ReachableViaCarrierDataNetwork : NetworkStatus.ReachableViaWiFiNetwork; + } + + public static NetworkStatus InternetConnectionStatus () + { + NetworkReachabilityFlags flags; + bool defaultNetworkAvailable = IsNetworkAvailable(out flags); + if (defaultNetworkAvailable && ((flags & NetworkReachabilityFlags.IsDirect) != 0)) + return NetworkStatus.NotReachable; + else if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) + return NetworkStatus.ReachableViaCarrierDataNetwork; + else if (flags == 0) + return NetworkStatus.NotReachable; + return NetworkStatus.ReachableViaWiFiNetwork; + } + + public static NetworkStatus LocalWifiConnectionStatus() + { + NetworkReachabilityFlags flags; + if (IsAdHocWiFiNetworkAvailable(out flags)) + if ((flags & NetworkReachabilityFlags.IsDirect) != 0) + return NetworkStatus.ReachableViaWiFiNetwork; + + return NetworkStatus.NotReachable; + } + } } diff --git a/ReachabilitySample/reachability.csproj b/ReachabilitySample/reachability.csproj index 40c1a7cb..90cc5dd4 100644 --- a/ReachabilitySample/reachability.csproj +++ b/ReachabilitySample/reachability.csproj @@ -3,59 +3,60 @@ Debug iPhoneSimulator + {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8.0.30703 2.0 {E1356D0A-1572-4157-BD97-05F0B9DA832E} - {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Exe reachability reachability - Xamarin.iOS v1.0 - True + true full - False + false bin\iPhoneSimulator\Debug DEBUG prompt 4 - None - True i386 + true + None none - False + false bin\iPhoneSimulator\Release prompt 4 - None i386 + None - True + true full - False + false bin\iPhone\Debug DEBUG prompt 4 - iPhone Developer - True ARMv7 + + + iPhone Developer + true none - False + false bin\iPhone\Release prompt 4 - iPhone Developer ARMv7, ARM64 + iPhone Developer @@ -64,14 +65,16 @@ - - MainWindow.xib - - + + + MainViewController.cs + + + - + diff --git a/ReachabilitySample/reachability.sln b/ReachabilitySample/reachability.sln index f7bb65aa..3d411a1c 100644 --- a/ReachabilitySample/reachability.sln +++ b/ReachabilitySample/reachability.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "reachability", "reachability.csproj", "{E1356D0A-1572-4157-BD97-05F0B9DA832E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reachability", "Reachability.csproj", "{E1356D0A-1572-4157-BD97-05F0B9DA832E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -20,7 +20,4 @@ Global {E1356D0A-1572-4157-BD97-05F0B9DA832E}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator {E1356D0A-1572-4157-BD97-05F0B9DA832E}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = reachability.csproj - EndGlobalSection EndGlobal