我不确定这是否可行,但我有这种情况。
我的UIWebView中显示了一个网站,该网站在UISegmentedController中设置了链接。 他们的网站可以检测您是在wifi上还是在3g网络上。
现在分段控制器指向2个不同的页面: 1 - iPhone友好的登录屏幕 2 - 登录后的主页。
现在问题是:
我是否可以对我的应用程序进行编程以检测它是WIFI还是3G(我知道你可以这样做),但是根据答案转到第1段或第2段
有点像这样:
if (iPhone device is on 3g) {
Go to Segment 1;
} else {
Go to Segment 0;
}
答案 0 :(得分:208)
使用Apple提供的代码here
Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus status = [reachability currentReachabilityStatus];
if(status == NotReachable)
{
//No internet
}
else if (status == ReachableViaWiFi)
{
//WiFi
}
else if (status == ReachableViaWWAN)
{
//3G
}
答案 1 :(得分:28)
如果您不想导入Reachability库或处理通知程序,可以使用这种简单的同步方法:
typedef enum {
ConnectionTypeUnknown,
ConnectionTypeNone,
ConnectionType3G,
ConnectionTypeWiFi
} ConnectionType;
+ (ConnectionType)connectionType
{
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, "8.8.8.8");
SCNetworkReachabilityFlags flags;
BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
CFRelease(reachability);
if (!success) {
return ConnectionTypeUnknown;
}
BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
BOOL isNetworkReachable = (isReachable && !needsConnection);
if (!isNetworkReachable) {
return ConnectionTypeNone;
} else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
return ConnectionType3G;
} else {
return ConnectionTypeWiFi;
}
}
答案 2 :(得分:18)
导入Apple的Reachability并尝试此操作
#import "Reachability.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
//Try this
Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus status = [reachability currentReachabilityStatus];
if(status == NotReachable)
{
NSLog(@"none");
//No internet
}
else if (status == ReachableViaWiFi)
{
NSLog(@"Wifi");
//WiFi
}
else if (status == ReachableViaWWAN)
{
NSLog(@"WWAN");
//connection type
CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
_carrier = [[netinfo subscriberCellularProvider] carrierName];
if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
NSLog(@"2G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
NSLog(@"2G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
NSLog(@"2G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
NSLog(@"3G");
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
NSLog(@"4G");
}
}
参考文献(未来链接可能会破裂):
答案 3 :(得分:8)
我制作了一个非常简单的基于块的Reachability包装器,它剥离了所有过时的C-like Reachability代码,并将其倾注到更多Cocoa形式。
用法如:
[EPPZReachability reachHost:hostNameOrIPaddress
completition:^(EPPZReachability *reachability)
{
if (reachability.reachableViaCellular) [self doSomeLightweightStuff];
}];
在Reachability with blocks for everyday use上查看eppz!blog,或直接从eppz!reachability at GitHub抓取。
也适用于IP地址,后来证明这是一种非常罕见的可达性包装功能。
答案 4 :(得分:5)
对于swift,我们可以使用:
func getNetworkType()->String {
do{
let reachability:Reachability = try Reachability.reachabilityForInternetConnection()
do{
try reachability.startNotifier()
let status = reachability.currentReachabilityStatus
if(status == .NotReachable){
return ""
}else if (status == .ReachableViaWiFi){
return "Wifi"
}else if (status == .ReachableViaWWAN){
let networkInfo = CTTelephonyNetworkInfo()
let carrierType = networkInfo.currentRadioAccessTechnology
switch carrierType{
case CTRadioAccessTechnologyGPRS?,CTRadioAccessTechnologyEdge?,CTRadioAccessTechnologyCDMA1x?: return "2G"
case CTRadioAccessTechnologyWCDMA?,CTRadioAccessTechnologyHSDPA?,CTRadioAccessTechnologyHSUPA?,CTRadioAccessTechnologyCDMAEVDORev0?,CTRadioAccessTechnologyCDMAEVDORevA?,CTRadioAccessTechnologyCDMAEVDORevB?,CTRadioAccessTechnologyeHRPD?: return "3G"
case CTRadioAccessTechnologyLTE?: return "4G"
default: return ""
}
// Get carrier name
}else{
return ""
}
}catch{
return ""
}
}catch{
return ""
}
}
答案 5 :(得分:2)
#import <ifaddrs.h>
#import <arpa/inet.h>
BOOL CheckWiFi() {
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
BOOL hasWifi = NO;
int err = getifaddrs(&interfaces);
if(err == 0) {
temp_addr = interfaces;
while(temp_addr) {
if(temp_addr->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)temp_addr->ifa_addr;
if(memcmp(temp_addr->ifa_name, "en", 2) == 0) {
hasWifi = YES;
break;
}
}
temp_addr = temp_addr->ifa_next;
}
}
freeifaddrs(interfaces);
return hasWifi;
}
要检查您是否在wifi中,这可以节省昂贵的连接检查。检查ifa_name“bridge”以检查互联网共享。
答案 6 :(得分:2)
类方法如下
+(NSString*)connectedNetworkType {
Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus status = [reachability currentReachabilityStatus];
if(status == NotReachable) {
NSLog(@"none");
//No internet
}
else if (status == ReachableViaWiFi) {
NSLog(@"Wifi");
//WiFi
return @"Wifi";
}
else if (status == ReachableViaWWAN){
NSLog(@"WWAN");
//connection type
CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
// _carrier = [[netinfo subscriberCellularProvider] carrierName];
if (([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x])) {
NSLog(@"2G");
return @"2G";
}
else if (([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB])
||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD])){
NSLog(@"3G");
return @"3G";
}
else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
NSLog(@"4G");
return @"4G";
}
}
return @"-1";//default unknown
}
答案 7 :(得分:1)
如果您使用的是Xamarin或Monotouch,可以使用Xamarin GitHub存储库中的Reachability改编类:
https://github.com/xamarin/monotouch-samples/blob/master/ReachabilitySample/reachability.cs
然后将其添加到您的项目中并致电Reachability.InternetConnectionStatus()
答案 8 :(得分:1)
在使用iOS 12或更高版本时,可以使用NWPathMonitor
代替史前的Reachability
类:
import Network // Put this on top of your class
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status != .satisfied {
// Not connected
}
else if path.usesInterfaceType(.cellular) {
// Cellular 3/4/5g connection
}
else if path.usesInterfaceType(.wifi) {
// Wi-fi connection
}
else if path.usesInterfaceType(.wiredEthernet) {
// Ethernet connection
}
}
monitor.start(queue: DispatchQueue.global(qos: .background))
答案 9 :(得分:1)
如果您不想使用可达性或使用Swift,那么简单的答案就在这里
答案 10 :(得分:1)
支持 5G 的 Swift 版本;基于几个答案。
import Foundation
import SystemConfiguration
import CoreTelephony
/// Returns current network connection type(e.g. 4G, WIFI). It may take some time; so there is the suggestion not to use it on the main queue.
static func connectionType() -> ConnectionType {
guard let reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "www.google.com") else {
return .noConnection
}
var flags = SCNetworkReachabilityFlags()
SCNetworkReachabilityGetFlags(reachability, &flags)
guard flags.contains(.reachable) else { return .noConnection }
guard flags.contains(.isWWAN) else { return .wifi }
let networkInfo = CTTelephonyNetworkInfo()
let carrierTypeName: String?
if #available(iOS 12.0, *) {
carrierTypeName = networkInfo.serviceCurrentRadioAccessTechnology?.first?.value
} else {
carrierTypeName = networkInfo.currentRadioAccessTechnology
}
if #available(iOS 14.0, *) {
switch carrierTypeName {
case CTRadioAccessTechnologyNR, CTRadioAccessTechnologyNRNSA:
return .cellular5G
default:
break
}
}
switch carrierTypeName {
case CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyEdge, CTRadioAccessTechnologyCDMA1x:
return .cellular2G
case CTRadioAccessTechnologyLTE:
return .cellular4G
case nil:
return .unknown
default:
return .cellular3G
}
}
enum ConnectionType: CustomStringConvertible {
case noConnection, unknown, wifi, cellular2G, cellular3G, cellular4G, cellular5G
var description: String {
switch self {
case .noConnection:
return "no connection"
case .unknown:
return "unknown"
case .wifi:
return "WIFI"
case .cellular2G:
return "2G"
case .cellular3G:
return "3G"
case .cellular4G:
return "LTE"
case .cellular5G:
return "5G"
}
}
}
答案 11 :(得分:0)
这是iOS 6的更新版本,其中包括来自苹果的SimplePing。它与ARC兼容,我从另一个人对Reachability的修复开始。 http://elbsolutions.com/projects/reachability-with-simpleping-wrapper/
我希望这有助于某人。
答案 12 :(得分:-2)
使用这个,使用Reachability构建并且易于使用,只需几行代码即可集成。有一个回调函数可以告诉你何时连接发生了变化 http://huytd.github.io/datatify/