我的应用中有一个“仅在 WiFi 上下载”的切换开关。然而,这种切换对于 iPod touch 或 WiFi-iPad 来说是没有用的。
有没有办法知道设备是否在代码中具有蜂窝数据功能?将来会起作用的东西也会很棒(例如,如果带有 3G 的 iPod touch 第 5 代问世)。
我的应用中有一个“仅在 WiFi 上下载”的切换开关。然而,这种切换对于 iPod touch 或 WiFi-iPad 来说是没有用的。
有没有办法知道设备是否在代码中具有蜂窝数据功能?将来会起作用的东西也会很棒(例如,如果带有 3G 的 iPod touch 第 5 代问世)。
嗨,您应该能够检查它是否具有 pdp_ip0 接口
#import <ifaddrs.h>
- (bool) hasCellular {
struct ifaddrs * addrs;
const struct ifaddrs * cursor;
bool found = false;
if (getifaddrs(&addrs) == 0) {
cursor = addrs;
while (cursor != NULL) {
NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
if ([name isEqualToString:@"pdp_ip0"]) {
found = true;
break;
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return found;
}
这不使用任何私有 API。
3G 本身似乎很难找到。您可以查看设备是否可以使用拨打电话[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]
。您可以使用可达性代码检查设备是否可以访问互联网、时间段(以及当前可以通过哪种方法):
NetworkStatus currentStatus = [[Reachability reachabilityForInternetConnection]
currentReachabilityStatus];
if(currentStatus == kReachableViaWWAN) // 3G
else if(currentStatus == kReachableViaWifi) // ...wifi
else if(currentStatus == kNotReachable) // no connection currently possible
..但除此之外,我认为您无法检查设备中是否存在 3G 调制解调器。***** 如果它无法拨打电话,并且当前没有打开手机数据并且wifi关闭,您将无法确定它是否支持3G。
另一种方法(虽然不向前兼容,所以您可能不想这样做)是将设备的型号与详尽的列表进行比较,知道哪些型号中有 3G 调制解调器,如此处所示。
***** 根据 Bentech 的回答,如果您想四处寻找设备名称(如果 Apple 决定更改 3g 接口名称,这可能会在没有预先警告的情况下停止工作),请致电getifaddrs
并检查pdp_ip0
接口。
@bentech 答案的 Swift 3.0 (UIDevice+Extension)
将此行添加到您的 BridgingHeader.h:
#import <ifaddrs.h>
别的地方:
extension UIDevice {
/// A Boolean value indicating whether the device has cellular data capabilities (true) or not (false).
var hasCellularCapabilites: Bool {
var addrs: UnsafeMutablePointer<ifaddrs>?
var cursor: UnsafeMutablePointer<ifaddrs>?
defer { freeifaddrs(addrs) }
guard getifaddrs(&addrs) == 0 else { return false }
cursor = addrs
while cursor != nil {
guard
let utf8String = cursor?.pointee.ifa_name,
let name = NSString(utf8String: utf8String),
name == "pdp_ip0"
else {
cursor = cursor?.pointee.ifa_next
continue
}
return true
}
return false
}
}
在 iOS 6.1 中,我已经能够使用Core Telephony成功检查是否存在蜂窝基带功能。这适用于我测试过的所有 iPad:Verizon 服务已激活和未激活,AT&T 服务当前已停用,SIM 卡进出,以及仅支持 Wi-Fi 的 iPad。
我使用的代码如下所示:
CTTelephonyNetworkInfo* ctInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = ctInfo.subscriberCellularProvider;
self.hasWWANCapability = carrier != nil;
对于所有具有蜂窝基带硬件的 iPad,carrier
并非没有。对于仅支持 Wi-Fi 的 iPad,carrier
为零。
一种方法是询问用户的位置。当它尽可能准确时,您将知道设备是否有 GPS。所有具有 GPS 的设备都将具有 3G。而那些没有 GPS 的将不会有 3G。
苹果在这里提供了代码。 https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html
您应该将 Reachability.h 和 Reachability.m 复制到您的项目并将 Reachability.h 导入您的类,然后
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
while (networkStatus==NotReachable) {
NSLog(@"not reachable");
//no internet connection
return;
}
while (networkStatus==ReachableViaWWAN) {
NSLog(@" ReachableViaWWAN ");
}
while (networkStatus==ReachableViaWiFi) {
NSLog(@"ReachableViaWiFi");
}
另一种方法是扩展这个:https ://github.com/monospacecollective/UIDevice-Hardware/blob/master/UIDevice-Hardware.m用这个:
-(bool) hasCellular:(NSString*)modelIdentifier {
if ([modelIdentifier hasPrefix:@"iPhone"]) return YES;
if ([modelIdentifier hasPrefix:@"iPod"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad1,1"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad2,1"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad2,2"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad2,3"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad2,4"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad2,5"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad2,6"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad2,7"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad3,1"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad3,2"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad3,3"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad3,4"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad3,5"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad3,6"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad4,1"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad4,2"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad2,5"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad2,6"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad2,7"]) return YES;
if ([modelIdentifier isEqualToString:@"iPad4,4"]) return NO;
if ([modelIdentifier isEqualToString:@"iPad4,5"]) return YES;
if ([modelIdentifier isEqualToString:@"i386"]) return NO;
if ([modelIdentifier isEqualToString:@"x86_64"]) return NO;
return YES;
}
(很明显,它可以被编辑以删除 NO 或 YES 仅取决于您想以哪种方式出错,以防万一有新模型......)