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

发布于 2024-11-30 07:07:17 字数 152 浏览 1 评论 0 原文

我的应用程序中有一个“仅通过 WiFi 下载”的切换开关。然而,该切换对于 iPod touch 或 WiFi-iPad 来说毫无用处。

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

I have a toggle in my app that's "download on WiFi only". However, that toggle is useless for iPod touch or WiFi-iPads.

Is there a way to know if the device has cellular data capabilities in code? Something that would work in the future would be great too (like if an iPod touch 5th gen with 3G comes out).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

是伱的 2024-12-07 07:07:17

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

Hi you should be able to check if it has the pdp_ip0 interface

#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;
}

This doesn't use any private APIs.

桜花祭 2024-12-07 07:07:17

3G 本身似乎很难找到。您可以使用[[了解设备是否可以拨打电话 UIApplicationsharedApplication] 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 接口。

3G by itself seems tough to find. You can find out whether a device can make calls using [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]. You can check whether a device can get to the internet, period (and by which method that can currently happen) using Reachability code:

NetworkStatus currentStatus = [[Reachability reachabilityForInternetConnection] 
                               currentReachabilityStatus];

if(currentStatus == kReachableViaWWAN) // 3G

else if(currentStatus == kReachableViaWifi) // ...wifi

else if(currentStatus == kNotReachable) // no connection currently possible

..but aside from that, I don't think you can check for the existence of a 3G modem in the device.***** If it can't make a call, and doesn't currently have cell data turned on and wifi turned off, you won't be able to find out if it's 3G-capable.

An alternative way (not forward-compatible though, so you probably don't want to do this) is to compare the device's model with an exhaustive list, knowing which ones have 3G modems in them, as shown here.

***** As per bentech's answer, if you want to go digging around with device names (this may stop working with no advance warning if Apple decide to change the 3g interface name), call getifaddrs and check for the pdp_ip0 interface.

瑾夏年华 2024-12-07 07:07:17

@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
    }
}

Swift 3.0 (UIDevice+Extension) of @bentech's answer

Add this line to your BridgingHeader.h:

#import <ifaddrs.h>

Somewhere else:

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
    }
}
晨曦÷微暖 2024-12-07 07:07:17

在 iOS 6.1 中,我已经能够使用 Core电话成功检查蜂窝基带功能是否存在。这适用于我测试的所有 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,运营商 为零。

In iOS 6.1, I've been able to use Core Telephony to successfully check for the presence of cellular baseband capabilities. This works on all iPads I tested: Verizon with service activated and without, AT&T with service currently deactivated, SIM card in and out, and a Wi-Fi-only iPad.

The code I used looks like this:

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

For all the iPads with cellular baseband hardware, carrier is not nil. For the Wi-Fi-only iPad, carrier is nil.

一笔一画续写前缘 2024-12-07 07:07:17

我认为您应该能够使用 CoreTelephony框架

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

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

I'd think you should be able to use the CoreTelephony Framework.

It does call out that it is for carriers to use, so I am not sure if it is against TOS to access it.

Carriers can use this information to write applications that provide services only for their own subscribers

拥抱我好吗 2024-12-07 07:07:17

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

One way of doing it is to ask for the users location. When it is as accurate as possibLe, you will know if the device have GPS. All devices that have GPS will have 3G. And those that don't GPS won't have 3G.

随遇而安 2024-12-07 07:07:17

苹果在这里提供了代码。
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");
}

Apple provided code here.
https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html

You should copy Reachability.h and Reachability.m to your project and import
Reachability.h to your class,then

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");
}
初雪 2024-12-07 07:07:17

另一种方法是扩展它: 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;

}

(显然,可以对其进行编辑以删除“否”或“是”,仅取决于您想要的方式错误万一有新型号......)

Another way is to extend this: https://github.com/monospacecollective/UIDevice-Hardware/blob/master/UIDevice-Hardware.m with this:

-(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;

}

(Clearly it could be edited down to remove either the NO or YES only depending on which way you want to err in case there is a new model...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文