我想查看我是否在iOS上使用Cocoa Touch库或使用Cocoa库在macOS 上建立了Internet连接.
我想出了一个方法,使用一个NSURL.我这样做的方式似乎有点不可靠(因为即使谷歌有一天会失败并依赖第三方看起来很糟糕),而且如果谷歌没有回应,我可以查看其他网站的回复,在我的应用程序中看起来似乎很浪费并且不必要的开销
- (BOOL) connectedToInternet
{
NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
return ( URLString != NULL ) ? YES : NO;
}
Run Code Online (Sandbox Code Playgroud)
我做得不好,(更不用说stringWithContentsOfURL在iOS 3.0和macOS 10.4中被弃用)如果是这样,有什么更好的方法来实现这一目标?
当我尝试在我的iPhone上检查互联网连接时,我收到了一堆错误.任何人都可以帮我解决这个问题吗?
代码:
import Foundation
import SystemConfiguration
public class Reachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
var flags: SCNetworkReachabilityFlags = 0
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
return false
}
let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection) ? true : false
}
}
Run Code Online (Sandbox Code Playgroud)
代码中的错误:

如果不可读,错误1说:
'Int'不能转换为'SCNetworkReachabilityFlags'
错误2和3:
找不到接受提供的参数的'init'的重载
我知道这个问题似乎是许多其他问题的愚蠢,但是,我觉得这个简单的案例并没有得到很好的解释.来自Android和BlackBerry背景,HTTPUrlConnection如果没有可用连接,立即发出请求失败.这似乎是完全理智的行为,我很惊讶地发现NSURLConnection在iOS中没有效仿它.
我知道Apple(以及其他扩展它的人)提供了一个Reachability帮助确定网络状态的类.我很高兴第一次看到这一点并完全期望看到类似的内容bool isNetworkAvailable(),但令我惊讶的是,我发现了一个复杂的系统,需要通知注册和回调,以及一堆看似不必要的细节.肯定有更好的办法.
我的应用程序已经优雅地处理连接失败,包括没有连接.用户会收到失败通知,然后应用程序继续运行.
因此我的要求很简单:我可以在所有HTTP请求之前调用单个同步函数来确定我是否应该打扰实际发送请求.理想情况下,它不需要设置,只返回一个布尔值.
这在iOS上真的不可能吗?
我不确定这是否可行,但我有这种情况.
我的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;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试将此代码段转换为Swift.由于一些困难,我正在努力开始起飞.
- (BOOL) connectedToNetwork
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的第一个和主要问题是如何定义和使用C结构.在struct sockaddr_in zeroAddress;上面代码的第一行()中,我认为他们正在定义一个zeroAddress从struct sockaddr_in(?)调用的实例,我假设.我试着宣布var这样的话.
var zeroAddress …Run Code Online (Sandbox Code Playgroud) 我已经找到了几个代码来做我想做的事情(检查可达性),但似乎没有一个对我有用.我无法弄清楚为什么这不好玩.
我的项目中有reachability.h/m,我正在做
#import <SystemConfiguration/SystemConfiguration.h>
Run Code Online (Sandbox Code Playgroud)
我添加了框架.我也有:
#import "Reachability.h"
Run Code Online (Sandbox Code Playgroud)
在.m的顶部,我正在尝试使用可达性.
Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"http://www.google.com"]; // set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];
if(remoteHostStatus == NotReachable) {NSLog(@"no");}
else if (remoteHostStatus == ReachableViaWiFiNetwork) {NSLog(@"wifi"); }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) {NSLog(@"cell"); }
Run Code Online (Sandbox Code Playgroud)
这给了我各种各样的问题.我究竟做错了什么?我是一个好的程序员,我只是很难找到需要放在哪里以启用我想要做的事情,无论我想知道我想做什么或不想做什么.(太令人沮丧了)
更新:这是正在发生的事情.这是我的viewcontroller,我有
#import <SystemConfiguration/SystemConfiguration.h>
Run Code Online (Sandbox Code Playgroud)
和
#import "Reachability.h"
Run Code Online (Sandbox Code Playgroud)
设置.到目前为止,这是我最不喜欢的编程部分.可达性问题http://sneakyness.com/reachability.png
FWIW,我们从未在代码中实现这一点.需要访问互联网(进入抽奖活动和购买DVD)的两个功能不是主要功能.没有其他需要互联网访问.
我们只是将两个互联网视图的背景设置为告知用户必须连接到互联网以使用此功能的通知,而不是添加更多代码.它与应用程序界面的其余部分一致,并且做得很好/很有品味.他们在审批过程中没有提及任何相关信息,但我们确实接到了个人电话,以确认我们是否赠送了与电影有关的内容.根据他们通常含糊的协议,否则您不得进行抽奖活动.
我也认为这更严格地遵守他们的"只使用一些东西,如果你绝对需要它们"的思想.
我正在开发一个使用网络的iPhone应用程序.iPhone通过HTTP请求与我的服务器通信,应该可以在WiFi和3G上运行.
我目前NSURLConnection initWithRequest用来向我的服务器发送异步请求并获得响应(但我很快就会开始使用ASIHTTPRequest库)
我明白,对于这种应用程序(需要互联网连接的应用程序),我应该(必须?)使用Reachability.
在搜索网页并查看Apple的Reachability示例代码后,我仍然不了解一些基本内容:
可达性的主要目的是什么?
在Apple的示例中,他们检测到主机,WiFi和3G的网络问题,并向用户显示适当的消息.
这是Reachability的主要目的,向用户显示消息吗?或者我是否需要将其用于其他更实际的场景?例如,如果NSURLConnaction请求失败,我是否需要以某种方式使用Reachability重新发送请求?
可达性的正确使用是什么?
在应用启动时只使用一个实例,然后收听网络更改是否常见?或者我应该在每次网络请求之前检查自己的可达性状态?
是否足以使用reachabilityWithHostName或者我也需要reachabilityForLocalWiFi和reachabilityForInternetConnection?
还有一件事,我理解苹果可以拒绝使用网络但不使用可达性的应用程序.我应该实施
哪些" 必须 "的方法?
仅通知用户目前没有互联网是否足够?
在iOS5中使用Apple的Reachability代码,我得到了一堆编译错误,如下所示.关于这里发生了什么的任何想法?我正在使用ARC,所以我稍微编辑了标准代码以删除autorelease/retain和NSAutoReleasePool.
架构armv7的未定义符号:
"_SCNetworkReachabilityCreateWithAddress",引自:Reachability.o中的:+ [Reachability reachabilityWithAddress:]
"_SCNetworkReachabilityCreateWithName",引自:Reachability.o中的+ [Reachability reachabilityWithHostName:]
"_SCNetworkReachabilityUnscheduleFromRunLoop",引自: - Reachability.o中的[Reachability stopNotifier]
"_SCNetworkReachabilityScheduleWithRunLoop",引自: - Reachability.o中的[Reachability startNotifier]
"_SCNetworkReachabilitySetCallback",引自: - Reachability.o中的[Reachability startNotifier]
"_SCNetworkReachabilityGetFlags",引自: - Reachability.o中的[ - Reachability connectionRequired] - Reachability.o中的[Reachability currentReachabilityStatus]
ld:找不到架构armv7 clang的符号:错误:链接器命令失败,退出代码为1(使用-v查看调用)
有没有人在iOS5下为ARC提供可行的可达性代码?
我正在尝试将网络连接检测集成到我的应用程序中,但是,由于我的网络更改未被检测到/打印到控制台中,因此我似乎在某处出错.
正如帖子中提到的,我目前正在使用以下类和工具来完成这项工作:
{.h, .m} NSNotificationCenter码
在AppDelegate.Swift中,我设置了NSNotificationCenter检测更改:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// ...
// A: Checks if the device is connected to the internet
var defaultCenter: Void = NSNotificationCenter().addObserver(self, selector:"checkForReachability", name: kReachabilityChangedNotification, object: nil)
Run Code Online (Sandbox Code Playgroud)
}
在同一个类中AppDelegate,我还创建了此函数,以便在发生更改时触发:
func checkForReachability () {
var networkReachability = Reachability.reachabilityForInternetConnection()
networkReachability.startNotifier()
var remoteHostStatus = networkReachability.currentReachabilityStatus()
if (remoteHostStatus.value == NotReachable.value) {
println("Not Reachable")
} else if (remoteHostStatus.value == ReachableViaWiFi.value) {
println("Reachable …Run Code Online (Sandbox Code Playgroud) reachability ×10
ios ×8
iphone ×3
objective-c ×3
swift ×3
wifi ×2
3g ×1
app-store ×1
c ×1
cocoa ×1
cocoa-touch ×1
ios5 ×1
macos ×1
struct ×1
xcode ×1