Created
February 7, 2015 19:09
-
-
Save claudiosanchez/948f4105e993e7ca9274 to your computer and use it in GitHub Desktop.
Network Reachability for Xamarin.iOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using Framework.Services.Network; | |
using MonoTouch.CoreFoundation; | |
using MonoTouch.SystemConfiguration; | |
namespace Framework.iOS.Services.Network | |
{ | |
/// <summary> | |
/// The reachability utility class. | |
/// </summary> | |
public static class Reachability | |
{ | |
private static NetworkReachability adHocWiFiNetworkReachability; | |
private static NetworkReachability defaultRouteReachability; | |
private static NetworkReachability remoteHostReachability; | |
/// <summary> | |
/// Checks if network is reachable without requiring connection. | |
/// </summary> | |
/// <param name="flags"> | |
/// The reachability flags. | |
/// </param> | |
/// <returns> | |
/// True if reachable, false if connection is required. | |
/// </returns> | |
public static bool IsReachableWithoutRequiringConnection(NetworkReachabilityFlags flags) | |
{ | |
return (flags & NetworkReachabilityFlags.Reachable) != 0 && | |
(((flags & NetworkReachabilityFlags.IsWWAN) != 0) || (flags & NetworkReachabilityFlags.ConnectionRequired) == 0); | |
} | |
/// <summary> | |
/// Determines if host is reachable. | |
/// </summary> | |
/// <param name="host"> | |
/// The host address. | |
/// </param> | |
/// <returns> | |
/// True if host is reachable, otherwise false. | |
/// </returns> | |
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; | |
} | |
/// <summary> | |
/// The reachability changed event. | |
/// </summary> | |
/// <remarks> | |
/// 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. | |
/// </remarks> | |
public static event EventHandler ReachabilityChanged; | |
/// <summary> | |
/// Determines if AdHoc WiFi network is available. | |
/// </summary> | |
/// <param name="flags"> | |
/// Optional extra network reachability flags. | |
/// </param> | |
/// <returns> | |
/// Returns true if it is possible to reach the AdHoc WiFi network, otherwise false. | |
/// </returns> | |
public static bool IsAdHocWiFiNetworkAvailable(out NetworkReachabilityFlags flags) | |
{ | |
if (adHocWiFiNetworkReachability == null) | |
{ | |
adHocWiFiNetworkReachability = new NetworkReachability(new IPAddress(new byte[] { 169, 254, 0, 0 })); | |
adHocWiFiNetworkReachability.SetCallback(OnChange); | |
adHocWiFiNetworkReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); | |
} | |
if (!adHocWiFiNetworkReachability.TryGetFlags(out flags)) | |
return false; | |
return IsReachableWithoutRequiringConnection(flags); | |
} | |
/// <summary> | |
/// The remote host status. | |
/// </summary> | |
/// <param name="hostName"> | |
/// The host name. | |
/// </param> | |
/// <returns> | |
/// The <see cref="NetworkStatus"/>. | |
/// </returns> | |
public static NetworkStatus RemoteHostStatus(string hostName) | |
{ | |
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.SetCallback(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; | |
} | |
/// <summary> | |
/// The internet connection status. | |
/// </summary> | |
/// <returns> | |
/// The <see cref="NetworkStatus"/>. | |
/// </returns> | |
public static NetworkStatus InternetConnectionStatus() | |
{ | |
NetworkReachabilityFlags flags; | |
if ((IsNetworkAvailable(out flags) && ((flags & NetworkReachabilityFlags.IsDirect) != 0)) || flags == 0) | |
{ | |
return NetworkStatus.NotReachable; | |
} | |
return (flags & NetworkReachabilityFlags.IsWWAN) != 0 ? | |
NetworkStatus.ReachableViaCarrierDataNetwork : | |
NetworkStatus.ReachableViaWiFiNetwork; | |
} | |
/// <summary> | |
/// The local WiFi connection status. | |
/// </summary> | |
/// <returns> | |
/// The <see cref="NetworkStatus"/>. | |
/// </returns> | |
public static NetworkStatus LocalWifiConnectionStatus() | |
{ | |
NetworkReachabilityFlags flags; | |
return (!IsAdHocWiFiNetworkAvailable(out flags) || (flags & NetworkReachabilityFlags.IsDirect) == 0) ? | |
NetworkStatus.NotReachable : | |
NetworkStatus.ReachableViaWiFiNetwork; | |
} | |
private static void OnChange(NetworkReachabilityFlags flags) | |
{ | |
var h = ReachabilityChanged; | |
if (h != null) | |
{ | |
h(null, EventArgs.Empty); | |
} | |
} | |
/// <summary> | |
/// Returns network reachability flags and network availability. | |
/// </summary> | |
/// <param name="flags"> | |
/// The network reachability flags. | |
/// </param> | |
/// <returns> | |
/// True if network is available, otherwise false. | |
/// </returns> | |
public static bool IsNetworkAvailable(out NetworkReachabilityFlags flags) | |
{ | |
if (defaultRouteReachability == null) | |
{ | |
defaultRouteReachability = new NetworkReachability(new IPAddress(0)); | |
defaultRouteReachability.SetCallback(OnChange); | |
defaultRouteReachability.Schedule(CFRunLoop.Current, CFRunLoop.ModeDefault); | |
} | |
return defaultRouteReachability.TryGetFlags(out flags) && IsReachableWithoutRequiringConnection(flags); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment