-
Notifications
You must be signed in to change notification settings - Fork 87
/
UIDevice_Extended.mm
114 lines (94 loc) · 3.37 KB
/
UIDevice_Extended.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 3.0 Edition
BSD License for anything not specifically marked as developed by a third party.
Apple's code excluded.
Use at your own risk
*/
#import <SystemConfiguration/SystemConfiguration.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <ifaddrs.h>
#import "UIDevice_Extended.h"
SCNetworkConnectionFlags connectionFlags;
@implementation UIDevice (Reachability)
// Matt Brown's get WiFi IP addy solution
// http://mattbsoftware.blogspot.com/2009/04/how-to-get-ip-address-of-iphone-os-v221.html
+ (NSString *) ipAddressWithPredicate:(NSPredicate *)isMatchNetworkInterfaceName
{
BOOL success;
NSString * wifiIPAddress = nil;
struct ifaddrs * addrList = NULL;
const struct ifaddrs * cursor;
success = getifaddrs(&addrList) == 0;
if (success)
{
for (cursor = addrList; cursor != NULL; cursor = cursor->ifa_next)
{
// the second test keeps from picking up the loopback address
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
NSString *name = @(cursor->ifa_name);
if ([isMatchNetworkInterfaceName evaluateWithObject:name])
{
wifiIPAddress = [NSString stringWithUTF8String:
(inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr))];
break;
}
}
}
freeifaddrs(addrList);
}
return wifiIPAddress;
}
+ (NSString *) localWiFiIPAddress
{
NSString * wifiIPAddress = nil;
NSPredicate * isMatchWIFIInterfaceName = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"en\\d+"];
// Get wifi adapter IP adress
wifiIPAddress = [[self class] ipAddressWithPredicate:isMatchWIFIInterfaceName];
if (wifiIPAddress == nil)
{
// Get hotspot IP address, if the bridge presents
NSPredicate * isMatchHotspotInterfaceName = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"bridge\\d+"];
wifiIPAddress = [[self class] ipAddressWithPredicate:isMatchHotspotInterfaceName];
}
return wifiIPAddress;
}
#pragma mark Checking Connections
+ (void) pingReachabilityInternal
{
BOOL ignoresAdHocWiFi = NO;
struct sockaddr_in ipAddress;
bzero(&ipAddress, sizeof(ipAddress));
ipAddress.sin_len = sizeof(ipAddress);
ipAddress.sin_family = AF_INET;
ipAddress.sin_addr.s_addr = htonl(ignoresAdHocWiFi ? INADDR_ANY : IN_LINKLOCALNETNUM);
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr *)&ipAddress);
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &connectionFlags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
LOG_NETWORK_SOCKS(NSLOGGER_LEVEL_ERROR, @"Error. Could not recover network reachability flags");
}
}
+ (BOOL)isNetworkAvailable
{
[self pingReachabilityInternal];
BOOL isReachable = ((connectionFlags & kSCNetworkFlagsReachable) != 0);
BOOL needsConnection = ((connectionFlags & kSCNetworkFlagsConnectionRequired) != 0);
return (isReachable && !needsConnection) ? YES : NO;
}
+ (BOOL)hasActiveWWAN
{
if (![self isNetworkAvailable])
return NO;
return ((connectionFlags & kSCNetworkReachabilityFlagsIsWWAN) != 0);
}
+ (BOOL) activeWLAN
{
return ([UIDevice localWiFiIPAddress] != nil);
}
@end