31

我的应用中有一个“仅在 WiFi 上下载”的切换开关。然而,这种切换对于 iPod touch 或 WiFi-iPad 来说是没有用的。

有没有办法知道设备是否在代码中具有蜂窝数据功能?将来会起作用的东西也会很棒(例如,如果带有 3G 的 iPod touch 第 5 代问世)。

4

8 回答 8

35

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

于 2013-01-24T17:36:05.640 回答
16

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接口。

于 2011-08-18T01:14:29.237 回答
6

@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
    }
}
于 2017-03-03T17:11:11.103 回答
4

在 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为零。

于 2013-07-12T21:28:19.943 回答
2

我认为您应该能够使用CoreTelephony Framework

它确实表明它是供运营商使用的,所以我不确定访问它是否违反 TOS。

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

于 2013-01-24T17:39:25.250 回答
1

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

于 2013-01-18T08:28:40.180 回答
0

苹果在这里提供了代码。 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");
}
于 2014-02-26T06:56:24.853 回答
-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 仅取决于您想以哪种方式出错,以防万一有新模型......)

于 2014-07-15T23:32:55.017 回答