Cocoa Touch를 사용하여 iOS에서 인터넷에 연결되어 있는지 확인하고 싶습니다. 라이브러리를 또는 Cocoa 라이브러리를 사용하는 macOS .
나는 이것을 사용하여 이것을 수행하는 방법을 생각해 냈습니다 NSURL
. 내가 한 방식은 약간 신뢰할 수없는 것 같습니다 (Google조차도 언젠가 다운되어 타사에 의존 할 수 있기 때문에 나쁜 것 같습니다) .Google이 응답하지 않으면 다른 웹 사이트의 응답을 확인할 수 있지만 내 응용 프로그램에서 낭비되고 불필요한 오버 헤드로 보입니다.
- (BOOL) connectedToInternet
{
NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
return ( URLString != NULL ) ? YES : NO;
}
내가 한 일이 잘못 stringWithContentsOfURL
되었습니까 (iOS 3.0 및 macOS 10.4에서는 더 이상 사용되지 않습니다) 그렇다면 그렇게하는 더 좋은 방법은 무엇입니까?
답변
중요 :이 점검은 항상 비동기 적으로 수행 해야합니다 . 아래 답변의 대부분은 동기식이므로 그렇지 않으면 앱이 중지됩니다.
빠른
1) CocoaPods 또는 Carthage를 통해 설치 하십시오 : https://github.com/ashleymills/Reachability.swift
2) 폐쇄를 통한 접근성 테스트
let reachability = Reachability()!
reachability.whenReachable = { reachability in
if reachability.connection == .wifi {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
}
reachability.whenUnreachable = { _ in
print("Not reachable")
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
목표 -C
1) SystemConfiguration
프로젝트에 프레임 워크를 추가 하지만 어디서나 포함시키는 것에 대해 걱정하지 마십시오.
2)의 토니 만의 버전을 추가 Reachability.h
하고 Reachability.m
프로젝트에 (여기 : https://github.com/tonymillion/Reachability )
3) 인터페이스 섹션 업데이트
#import "Reachability.h"
// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
Reachability *internetReachableFoo;
}
@end
4) 그런 다음이 메소드를 호출 할 수있는 뷰 컨트롤러의 .m 파일에 구현하십시오.
// Checks if we have an internet connection or not
- (void)testInternetConnection
{
internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Yayyy, we have the interwebs!");
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Someone broke the internet :(");
});
};
[internetReachableFoo startNotifier];
}
중요 참고 :Reachability
다른 프로젝트와 이름 충돌로 실행할 수 있도록 클래스를 프로젝트에 가장 많이 사용되는 클래스 중 하나입니다. 이 경우, 당신은 쌍 중 하나의 이름을 변경해야 Reachability.h
하고Reachability.m
문제를 해결하려면 파일 파일 합니다.
참고 : 사용 하는 도메인은 중요하지 않습니다. 모든 도메인에 대한 게이트웨이를 테스트하고 있습니다.
답변
나는 일을 단순하게 유지하고 싶다. 내가하는 방법은 다음과 같습니다.
//Class.h
#import "Reachability.h"
#import <SystemConfiguration/SystemConfiguration.h>
- (BOOL)connected;
//Class.m
- (BOOL)connected
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return networkStatus != NotReachable;
}
그런 다음 연결이 있는지 확인할 때마다 이것을 사용합니다.
if (![self connected]) {
// Not connected
} else {
// Connected. Do some Internet stuff
}
이 방법은 네트워크 상태가 변경 될 때까지 기다리지 않습니다. 요청하면 상태 만 테스트합니다.
답변
Apple의 접근성 코드를 사용하여 클래스를 포함하지 않고도이를 올바르게 확인할 수있는 기능을 만들었습니다.
프로젝트에 SystemConfiguration.framework를 포함하십시오.
가져 오기 :
#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>
이제이 함수를 호출하십시오.
/*
Connectivity testing code pulled from Apple's Reachability Example: https://developer.apple.com/library/content/samplecode/Reachability
*/
+(BOOL)hasConnectivity {
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
if (reachability != NULL) {
//NetworkStatus retVal = NotReachable;
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
{
// If target host is not reachable
return NO;
}
if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
// If target host is reachable and no connection is required
// then we'll assume (for now) that your on Wi-Fi
return YES;
}
if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
{
// ... and the connection is on-demand (or on-traffic) if the
// calling application is using the CFSocketStream or higher APIs.
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
{
// ... and no [user] intervention is needed
return YES;
}
}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
// ... but WWAN connections are OK if the calling application
// is using the CFNetwork (CFSocketStream?) APIs.
return YES;
}
}
}
return NO;
}
그리고 그것은 당신을 위해 테스트 된 iOS 5 입니다.
답변
이것은 정답 이었지만 지금은 도달 가능성에 대한 알림을 구독해야하므로 구식입니다. 이 방법은 동 기적으로 확인합니다.
Apple의 Reachability 클래스를 사용할 수 있습니다. 또한 Wi-Fi가 활성화되어 있는지 확인할 수 있습니다.
Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"www.example.com"]; // Set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];
if (remoteHostStatus == NotReachable) { }
else if (remoteHostStatus == ReachableViaWiFiNetwork) { }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { }
연결성 클래스는 SDK와 함께 제공되지 않고이 Apple 샘플 응용 프로그램 의 일부입니다 . 다운로드하여 프로젝트에 Reachability.h / m을 복사하십시오. 또한 프로젝트에 SystemConfiguration 프레임 워크를 추가해야합니다.
답변
다음은 매우 간단한 답변입니다.
NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data)
NSLog(@"Device is connected to the Internet");
else
NSLog(@"Device is not connected to the Internet");
URL은 매우 작은 웹 사이트를 가리켜 야합니다. 여기에서는 Google의 모바일 웹 사이트를 사용하지만 신뢰할 수있는 웹 서버가있는 경우 최대 속도를 위해 문자가 하나만있는 작은 파일을 업로드 했습니다 .
장치가 어떻게 든 인터넷에 연결되어 있는지 확인하는 것이 원하는 모든 것이라면이 간단한 솔루션을 사용하는 것이 좋습니다. 사용자의 연결 방법을 알아야하는 경우 도달 가능성을 사용하는 것이 좋습니다.
주의 : 스레드가 웹 사이트를로드하는 동안 스레드가 잠시 차단됩니다. 내 경우에는 이것이 문제가되지 않았지만 이것을 고려해야합니다 (브래드가 이것을 지적한 것에 대한 신용).
답변
내 앱에서 수행하는 방법은 다음과 같습니다. 200 상태 응답 코드는 아무것도 보장하지 않지만 충분히 안정적입니다. 내 HEAD 응답을 확인하기 때문에 여기에 게시 된 NSData 답변만큼 많은로드가 필요하지 않습니다.
스위프트 코드
func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let url = NSURL(string: "http://www.google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
{(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
let rsp = response as! NSHTTPURLResponse?
completionHandler(internet:rsp?.statusCode == 200)
})
}
func yourMethod()
{
self.checkInternet(false, completionHandler:
{(internet:Bool) -> Void in
if (internet)
{
// "Internet" aka Google URL reachable
}
else
{
// No "Internet" aka Google URL un-reachable
}
})
}
오브젝티브 -C 코드
typedef void(^connection)(BOOL);
- (void)checkInternet:(connection)block
{
NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
headRequest.HTTPMethod = @"HEAD";
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
defaultConfigObject.timeoutIntervalForResource = 10.0;
defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:headRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if (!error && response)
{
block([(NSHTTPURLResponse *)response statusCode] == 200);
}
}];
[dataTask resume];
}
- (void)yourMethod
{
[self checkInternet:^(BOOL internet)
{
if (internet)
{
// "Internet" aka Google URL reachable
}
else
{
// No "Internet" aka Google URL un-reachable
}
}];
}