了解iOS设备是否具有蜂窝数据功能

时间:2011-08-18 00:52:53

标签: iphone objective-c ios uidevice cellular-network

我的应用中有一个切换,即“仅在WiFi上下载”。但是,这种切换对于iPod touch或WiFi-iPad来说毫无用处。

有没有办法知道设备是否具有代码中的蜂窝数据功能?未来可行的东西也会很棒(比如带有3G的iPod touch第五代产品)。

8 个答案:

答案 0 :(得分:32)

您好,您应该能够检查它是否具有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。

答案 1 :(得分:16)

3G本身似乎很难找到。您可以使用[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]查看设备是否可以拨打电话。您可以使用Reachability代码检查设备是否可以访问互联网,期间(以及当前发生的方法):

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。

另一种方法(虽然不是向前兼容的,所以你可能不想这样做)是将设备的模型与详尽的列表进行比较,知道哪些有调制解调器,如图所示{{3} }。

*****根据bentech的回答,如果您想要了解设备名称(如果Apple决定更改3g接口名称,可能会停止工作而不提前警告),请致电getifaddrs并检查pdp_ip0界面。

答案 2 :(得分:6)

@ bentech的回答的Swift 3.0(UIDevice +扩展)

将此行添加到您的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
    }
}

答案 3 :(得分:4)

在iOS 6.1中,我已经能够使用Core Telephony成功检查是否存在蜂窝基带功能。这适用于我测试的所有iPad:Verizon已启用服务但没有,AT&amp; T服务当前已停用,SIM卡进出,以及仅支持Wi-Fi的iPad。

我使用的代码如下所示:

CTTelephonyNetworkInfo* ctInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = ctInfo.subscriberCellularProvider;
self.hasWWANCapability = carrier != nil;

对于所有使用蜂窝基带硬件的iPad,carrier不是零。对于仅支持Wi-Fi的iPad,carrier为零。

答案 4 :(得分:2)

我认为你应该可以使用CoreTelephony Framework

它确实指出它是供运营商使用的,所以我不确定它是否反对TOS来访问它。

  

运营商可以使用此信息编写仅为其订户提供服务的应用程序

答案 5 :(得分:1)

这样做的一种方法是询问用户位置。当它尽可能准确时,您将知道该设备是否具有GPS。所有拥有GPS的设备都将拥有3G。那些没有GPS的人将不会拥有3G。

答案 6 :(得分:1)

Apple提供了代码。 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");
}

答案 7 :(得分:-3)

另一种方法是将此扩展: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,具体取决于您希望在出现新模型时出错的方式......)