查漏补缺集是自己曾经做过相关的功能,但是重做相关功能或者重新看到相关功能的实现,感觉理解上更深刻。这一类的文章集中记录在查漏补缺集。
iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可能是与WiFi相关的。
1.Ping域名、Ping某IP
有时候可能会遇到ping 某个域名或者ip通不通,再做下一步操作。这里的ping与传统的做get或者post请求还是有很大区别的。比如我们连接了某个WiFi,测试ping www.baidu.com,如果能ping 通,基本可以断定可以上网了,但是如果我们做了一个get 请求(url 是www.baidu.com),路由器可能重定向这个WiFi内的某网页了,依然没有错误返回,就会误认为可以正常上网。
这里有关于ping命令的详细解释:百度百科Ping
iOS中想要ping域名或者ip,苹果提供了一个官方例子SimplePing
在例子中,有一个苹果已经封装过的类【SimplePing.h】和【SimplePing.m】
使用起来也相当的简单:
首先创建一个Ping对象:
1
2
3
4
5
|
SimplePing *pinger = [[SimplePing alloc] initWithHostName:self.hostName];
self.pinger = pinger;
pinger.delegate = self;
pinger.addressStyle = SimplePingAddressStyleICMPv4;
[pinger start];
|
然后在start成功的代理方法中,发送数据报文:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/** * start成功,也就是准备工作做完后的回调
*/
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address { // 发送测试报文数据
[self.pinger sendPingWithData:nil];
} - (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error { NSLog(@ "didFailWithError" );
[self.pinger stop];
} |
其他几个代理方法也非常简单,就简单记录一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 发送测试报文成功的回调方法 - (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber { NSLog(@ "#%u sent" , sequenceNumber);
} //发送测试报文失败的回调方法 - (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error { NSLog(@ "#%u send failed: %@" , sequenceNumber, error);
} // 接收到ping的地址所返回的数据报文回调方法 - (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber { NSLog(@ "#%u received, size=%zu" , sequenceNumber, packet.length);
} - (void)simplePing:(SimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet { NSLog(@ "#%s" ,__func__);
} |
注意点:
iOS 中 ping失败后(即发送测试报文成功后,一直没后收到响应的报文),不会有任何回调方法告知我们。而一般ping 一次的结果也不太准确,ping 花费的时间也非常短,所以我们一般会ping多次,发送一次ping 测试报文0.5s后检测一下这一次ping是否已经收到响应。0.5s后检测时,如果已经收到响应,则可以ping 通;如果没有收到响应,则视为超时。
做法也有很多种,可以用NSTimer或者 {- (void)performSelector: withObject:afterDelay:}
这里有一个别人写的工程:https://github.com/lovesunstar/STPingTest
PingTest效果图
终端ping效果图
2.获取WiFi信息
以前物联网刚火的时候,出现过很多一体式无线路由,所以App里难免会遇到要判断当前所连接的WiFi,以及获取WiFi信息的功能。13年的时候查过一些关于WiFi的方法,后面渐渐都忘记了。惭愧!!!
需要添加SystemConfiguration.framework 并在当前类中添加代码#import
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//获取WiFi 信息,返回的字典中包含了WiFi的名称、路由器的Mac地址、还有一个Data(转换成字符串打印出来是wifi名称) - (NSDictionary *)fetchSSIDInfo { NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
if (!ifs) {
return nil;
}
NSDictionary *info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info && [info count]) { break ; }
}
return info;
} //打印出来的结果: 2016-05-12 15:28:51.674 SimplePing[18883:6790207] WIFI_INFO:{ BSSID = "a4:2b:8c:c:7f:bd" ;
SSID = bdmy06;
SSIDDATA = ;
} |
3.获取WiFi名称
有了上一步,获取WiFi名称就非常简单了。
1
2
3
|
NSString *WiFiName = info[@ "SSID" ];
//打印结果: 2016-05-12 15:35:13.059 SimplePing[18887:6791418] bdmy06 |
完整的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
- (NSString *)fetchWiFiName { NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
if (!ifs) {
return nil;
}
NSString *WiFiName = nil;
for (NSString *ifnam in ifs) {
NSDictionary *info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info && [info count]) {
// 这里其实对应的有三个key:kCNNetworkInfoKeySSID、kCNNetworkInfoKeyBSSID、kCNNetworkInfoKeySSIDData,
// 不过它们都是CFStringRef类型的
WiFiName = [info objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
// WiFiName = [info objectForKey:@"SSID"]; break ;
}
}
return WiFiName;
} |
4.获取当前所连接WiFi的网关地址
例如自己家的路由器一般默认的网关地址是192.168.1.1,获取的就是这个192.168.1.1。
为什么不直接写死呢?
因为一些商场或者有多个路由器的网关地址是不一样的,比如之前有个公司的网关是192.168.89.1。
这里有篇博客,这是地址
需要导入的库:
1
|
#import #import #import |
获取网关的方法
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
|
- (NSString *)getGatewayIpForCurrentWiFi { NSString *address = @ "error" ;
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
//*/
while (temp_addr != NULL) {
/*/
int i=255;
while ((i--)>0)
//*/
if (temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@ "en0" ])
{
// Get NSString from C String //ifa_addr
//ifa->ifa_dstaddr is the broadcast address, which explains the "255's"
// address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
//routerIP----192.168.1.255 广播地址
NSLog(@ "broadcast address--%@" ,[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)]);
//--192.168.1.106 本机地址
NSLog(@ "local device ip--%@" ,[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]);
//--255.255.255.0 子网掩码地址
NSLog(@ "netmask--%@" ,[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)]);
//--en0 端口地址
NSLog(@ "interface--%@" ,[NSString stringWithUTF8String:temp_addr->ifa_name]);
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
in_addr_t i = inet_addr([address cStringUsingEncoding:NSUTF8StringEncoding]);
in_addr_t* x = &i;
unsigned char *s = getdefaultgateway(x);
NSString *ip=[NSString stringWithFormat:@ "%d.%d.%d.%d" ,s[0],s[1],s[2],s[3]];
free(s);
return ip;
} |
其中 getdefaultgateway 是一个C语言文件中的方法,在工程里可以找到。
5.获取本机在WiFi环境下的IP地址
获取本机在WiFi环境下的ip地址,在上一节中其实已经写过,这里将其提取出来即可:
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
|
- (NSString *)getLocalIPAddressForCurrentWiFi { NSString *address = nil;
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr != NULL) {
if (temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@ "en0" ]) {
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
return address;
}
}
temp_addr = temp_addr->ifa_next;
}
freeifaddrs(interfaces);
}
return nil;
} |
同样的方式也可以获取广播地址、子网掩码、端口等,组装成一个字典。
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
|
- (NSMutableDictionary *)getLocalInfoForCurrentWiFi { NSMutableDictionary *dict = [NSMutableDictionary dictionary];
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
//*/
while (temp_addr != NULL) {
if (temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@ "en0" ]) {
//----192.168.1.255 广播地址
NSString *broadcast = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
if (broadcast) {
[dict setObject:broadcast forKey:@ "broadcast" ];
}
NSLog(@ "broadcast address--%@" ,broadcast);
//--192.168.1.106 本机地址
NSString *localIp = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
if (localIp) {
[dict setObject:localIp forKey:@ "localIp" ];
}
NSLog(@ "local device ip--%@" ,localIp);
//--255.255.255.0 子网掩码地址
NSString *netmask = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)];
if (netmask) {
[dict setObject:netmask forKey:@ "netmask" ];
}
NSLog(@ "netmask--%@" ,netmask);
//--en0 端口地址
NSString *interface = [NSString stringWithUTF8String:temp_addr->ifa_name];
if (interface) {
[dict setObject:interface forKey:@ "interface" ];
}
NSLog(@ "interface--%@" ,interface);
return dict;
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return dict;
} |
将返回的字典打印出来:
1
2
3
4
5
6
|
2016-05-12 17:59:09.257 SimplePing[19141:6830567] wifi:{ broadcast = "192.168.1.255" ;
interface = en0;
localIp = "192.168.1.7" ;
netmask = "255.255.255.0" ;
} |
相关推荐
ArcGIS API For iOS 2.2.1及26个例程源代码 ArcGIS API for iOS 使您可使用 Objective C 构建多种应用程序(这些应用程序将运用 ArcGIS Server 提供的强大制图、地理编码、地理处理和自定义功能)并将它们部署到 ...
ArcGIS API For iOS Sample 20110830.zip
Implement machine learning models in your iOS applications. This short work begins by reviewing the primary principals of machine learning and then moves on to discussing more advanced topics, such as...
ios 苹果自带api实现ocr。支持iphone,ipad,Mac(catalyst)
使用ios原生API,实现二维码的扫描、生成及读取图片上的二维码,还有一个UIMenuController的实现Demo
对了解基于IOS开发ArcGIS移动系统有帮助
ArcGIS API For iOS 详解文档
ArcGIS API for iOS SDK 1.8 安装包 (请在Mac下安装)
Api-ios-pdk.zip,Pinterest iOS SDKCaveat——弃用,一个api可以被认为是多个软件设备之间通信的指导手册。例如,api可用于web应用程序之间的数据库通信。通过提取实现并将数据放弃到对象中,api简化了编程。
ArcGIS API for iOS 进阶
个人整理超精密的iOS笔记,ios常用API,对于平时比较整理的你。
ArcGIS API for iOS进阶_张宝才
ArcGIS-API-for-iOS进阶.pdf
仿ios6信号 有wifi图标修改
ArcGIS API for iOS 使您可使用 Objective C 构建多种应用程序(这些应用程序将运用 ArcGIS Server 提供的强大制图、地理编码、地理处理和自定义功能)并将它们部署到 Apple iPhone、iPod Touch 和 iPad 设备。API ...
ArcGIS API for iOS 使您可使用 Objective C 构建多种应用程序(这些应用程序将运用 ArcGIS Server 提供的强大制图、地理编码、地理处理和自定义功能)并将它们部署到 Apple iPhone、iPod Touch 和 iPad 设备。API ...
检查iOS源代码是否包含私有API工具,在提交AppStore审核前用这个工具检查一下十分必要,减少被拒的概率。
Basic Sensors in iOS 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn...
ArcGIS API for iOS 使您可使用 Objective C 构建多种应用程序(这些应用程序将运用 ArcGIS Server 提供的强大制图、地理编码、地理处理和自定义功能)并将它们部署到 Apple iPhone、iPod Touch 和 iPad 设备。API ...
ArcGIS API for iOS 使您可使用 Objective C 构建多种应用程序(这些应用程序将运用 ArcGIS Server 提供的强大制图、地理编码、地理处理和自定义功能)并将它们部署到 Apple iPhone、iPod Touch 和 iPad 设备。API ...