iOS에서 인터넷 연결을 감지하는 가장 쉬운 방법은 무엇입니까?
나는이 질문이 다른 많은 사람들의 속임수 인 것처럼 보이지만 간단한 사례가 여기에 잘 설명되어 있다고 생각하지 않습니다. HTTPUrlConnection
사용 가능한 연결이없는 경우 Android 및 BlackBerry 배경에서 가져와 요청을 즉시 실패하게합니다. 이것은 완전히 제정신의 행동처럼 보이고, NSURLConnection
iOS에서 그것을 모방하지 않았다는 사실에 놀랐 습니다.
Apple (및 Apple을 확장 한 다른 사람들) Reachability
은 네트워크 상태를 결정하는 데 도움이 되는 수업을 제공한다는 것을 이해합니다 . 나는 이것을 처음으로보고 기뻤고와 같은 것을 완전히 기대 bool isNetworkAvailable()
했지만 놀랍게도 알림 등록 및 콜백이 필요한 복잡한 시스템과 불필요한 것으로 보이는 세부 사항이 발견되었습니다. 더 좋은 방법이 있어야합니다.
내 앱은 이미 연결되지 않은 것을 포함하여 연결 실패를 정상적으로 처리합니다. 사용자에게 실패 알림이 표시되고 앱이 계속 진행됩니다.
따라서 내 요구 사항은 간단합니다. 단일, 동기 함수 모든 HTTP 요청 전에 호출하여 실제로 요청을 보내야하는지 여부를 결정할 수 있습니다. 이상적으로는 설정이 필요 없으며 부울 만 반환합니다.
iOS에서는 이것이 실제로 불가능합니까?
좀 더 연구를하고 더 최신 솔루션으로 답변을 업데이트하고 있습니다. 이미 살펴 보았는지 확실하지 않지만 Apple에서 제공하는 멋진 샘플 코드가 있습니다.
프로젝트에 Reachability.h 및 Reachability.m 파일을 포함하십시오. ReachabilityAppDelegate.m에서 호스트 도달 가능성, WiFi를 통한 도달 가능성, WWAN 등을 확인하는 방법에 대한 예를 살펴보십시오. 네트워크 연결 가능성을 간단히 확인하려면 다음과 같은 작업을 수행 할 수 있습니다.
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {
NSLog(@"There IS NO internet connection");
} else {
NSLog(@"There IS internet connection");
}
@ BenjaminPiette 's : 프로젝트에 SystemConfiguration.framework를 추가하는 것을 잊지 마십시오.
이 스레드 가이 유형의 질문에 대한 최고의 Google 결과 인 것처럼 보아서 나에게 맞는 솔루션을 제공 할 것이라고 생각했습니다. 이미 AFNetworking을 사용 하고 있었지만 검색 과정에서 프로젝트 중반까지 AFNetworking으로이 작업을 수행하는 방법이 밝혀지지 않았습니다.
당신이 원하는 것은 AFNetworkingReachabilityManager 입니다.
// -- Start monitoring network reachability (globally available) -- //
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"Reachability changed: %@", AFStringFromNetworkReachabilityStatus(status));
switch (status) {
case AFNetworkReachabilityStatusReachableViaWWAN:
case AFNetworkReachabilityStatusReachableViaWiFi:
// -- Reachable -- //
NSLog(@"Reachable");
break;
case AFNetworkReachabilityStatusNotReachable:
default:
// -- Not reachable -- //
NSLog(@"Not Reachable");
break;
}
}];
다음을 사용하여 도달 가능성을 동 기적으로 테스트 할 수도 있습니다 (한 번 모니터링이 시작된 경우).
-(BOOL) isInternetReachable
{
return [AFNetworkReachabilityManager sharedManager].reachable;
}
너무 늦게 답변 해 주셔서 죄송하지만이 답변이 향후 누군가에게 도움이 되었기를 바랍니다.
다음은 추가 클래스없이 인터넷 연결을 확인할 수있는 작은 네이티브 C 코드 스 니펫입니다.
다음 헤더를 추가하십시오.
#include<unistd.h>
#include<netdb.h>
암호:
-(BOOL)isNetworkAvailable
{
char *hostname;
struct hostent *hostinfo;
hostname = "google.com";
hostinfo = gethostbyname (hostname);
if (hostinfo == NULL){
NSLog(@"-> no connection!\n");
return NO;
}
else{
NSLog(@"-> connection established!\n");
return YES;
}
}
스위프트 3
func isConnectedToInternet() -> Bool {
let hostname = "google.com"
//let hostinfo = gethostbyname(hostname)
let hostinfo = gethostbyname2(hostname, AF_INET6)//AF_INET6
if hostinfo != nil {
return true // internet available
}
return false // no internet
}
나는 현재이 간단한 동기 방법을 사용하므로 프로젝트 나 대리인에 추가 파일이 필요하지 않습니다.
수입:
#import <SystemConfiguration/SCNetworkReachability.h>
이 메소드를 작성하십시오.
+(bool)isNetworkAvailable
{
SCNetworkReachabilityFlags flags;
SCNetworkReachabilityRef address;
address = SCNetworkReachabilityCreateWithName(NULL, "www.apple.com" );
Boolean success = SCNetworkReachabilityGetFlags(address, &flags);
CFRelease(address);
bool canReach = success
&& !(flags & kSCNetworkReachabilityFlagsConnectionRequired)
&& (flags & kSCNetworkReachabilityFlagsReachable);
return canReach;
}
그런 다음에 이것을 넣으면 MyNetworkClass
:
if( [MyNetworkClass isNetworkAvailable] )
{
// do something networky.
}
시뮬레이터에서 테스트하는 경우 Mac의 Wi-Fi를 켜거나 끄면 시뮬레이터가 전화 설정을 무시합니다.
최신 정보:
결국 메인 스레드를 차단하지 않기 위해 스레드 / 비동기 콜백을 사용했습니다. 정기적으로 다시 테스트하여 캐시 된 결과를 사용할 수 있습니다. 데이터 연결을 불필요하게 열어 두지 않아야합니다.
@thunk가 설명했듯이 더 나은 URL을 사용할 수 있으며 Apple 자체에서 사용합니다. http://cadinc.com/blog/why-your-apple-ios-7-device-wont-connect-to-the-wifi-network
구현이 끝났을 때 살펴보면 정말 간단합니다. 다시 한 번, 매우 간단합니다. 필요한 유일한 유일한 항목은 두 가지 부울 변수입니다. 인터넷 연결성과 호스트 연결성 ). 연결 상태를 결정할 수있는 도우미 클래스를 구성한 후에는 이러한 절차를 알기 위해 필요한 구현을 다시 신경 쓰지 않아도됩니다.
예:
#import <Foundation/Foundation.h>
@class Reachability;
@interface ConnectionManager : NSObject {
Reachability *internetReachable;
Reachability *hostReachable;
}
@property BOOL internetActive;
@property BOOL hostActive;
- (void) checkNetworkStatus:(NSNotification *)notice;
@end
그리고 .m 파일 :
#import "ConnectionManager.h"
#import "Reachability.h"
@implementation ConnectionManager
@synthesize internetActive, hostActive;
-(id)init {
self = [super init];
if(self) {
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];
hostReachable = [[Reachability reachabilityWithHostName:@"www.apple.com"] retain];
[hostReachable startNotifier];
return self;
}
- (void) checkNetworkStatus:(NSNotification *)notice {
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
NSLog(@"The internet is down.");
self.internetActive = NO;
break;
}
case ReachableViaWiFi:
{
NSLog(@"The internet is working via WIFI.");
self.internetActive = YES;
break;
}
case ReachableViaWWAN:
{
NSLog(@"The internet is working via WWAN.");
self.internetActive = YES;
break;
}
}
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
NSLog(@"A gateway to the host server is down.");
self.hostActive = NO;
break;
}
case ReachableViaWiFi:
{
NSLog(@"A gateway to the host server is working via WIFI.");
self.hostActive = YES;
break;
}
case ReachableViaWWAN:
{
NSLog(@"A gateway to the host server is working via WWAN.");
self.hostActive = YES;
break;
}
}
}
// If lower than SDK 5 : Otherwise, remove the observer as pleased.
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@end
누군가가 있다 전에 간단한, 재사용 가능한 방법으로이 문제를 해결했다. DDGReachability
.
편집 : 또는 tonymillion/Reachability
.
코드를 추출하여 하나의 단일 방법에 넣었습니다. 다른 방법이 도움이되기를 바랍니다.
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
#import <netinet6/in6.h>
...
- (BOOL)isInternetReachable
{
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);
SCNetworkReachabilityFlags flags;
if(reachability == NULL)
return false;
if (!(SCNetworkReachabilityGetFlags(reachability, &flags)))
return false;
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
// if target host is not reachable
return false;
BOOL isReachable = false;
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
isReachable = true;
}
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
isReachable = true;
}
}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
// ... but WWAN connections are OK if the calling application
// is using the CFNetwork (CFSocketStream?) APIs.
isReachable = true;
}
return isReachable;
}
도움이 될 것 같아요 ..
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
if([AFNetworkReachabilityManager sharedManager].isReachable)
{
NSLog(@"Network reachable");
}
else
{
NSLog(@"Network not reachable");
}
내가 허용 대답의 빠른 버전을 쓰고 있어요 여기에 , 넣다가이 유용한 사람을 발견하면, 코드가 빠른 2 작성,
SampleCode 에서 필요한 파일을 다운로드 할 수 있습니다
프로젝트에 추가 Reachability.h
및 Reachability.m
제출
이제 Bridging-Header.h
프로젝트에 파일이 없으면 파일 을 만들어야 합니다.
Bridging-Header.h
파일 안에 다음 줄을 추가하십시오.
#import "Reachability.h"
이제 인터넷 연결을 확인하려면
static func isInternetAvailable() -> Bool {
let networkReachability : Reachability = Reachability.reachabilityForInternetConnection()
let networkStatus : NetworkStatus = networkReachability.currentReachabilityStatus()
if networkStatus == NotReachable {
print("No Internet")
return false
} else {
print("Internet Available")
return true
}
}
프로젝트에서 이미 AFNetworking을 구성한 경우이 방법을 시도 할 수도 있습니다.
-(void)viewDidLoad{ // -- add connectivity notification --//
[[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(ReachabilityDidChangeNotification:) name:AFNetworkingReachabilityDidChangeNotification object:nil];}
-(void)ReachabilityDidChangeNotification:(NSNotification *)notify
{
// -- NSLog(@"Reachability changed: %@", AFStringFromNetworkReachabilityStatus(status)); -- //
NSDictionary *userInfo =[notif userInfo];
AFNetworkReachabilityStatus status= [[userInfo valueForKey:AFNetworkingReachabilityNotificationStatusItem] intValue];
switch (status)
{
case AFNetworkReachabilityStatusReachableViaWWAN:
case AFNetworkReachabilityStatusReachableViaWiFi:
// -- Reachable -- //
// -- Do your stuff when internet connection is available -- //
[self getLatestStuff];
NSLog(@"Reachable");
break;
case AFNetworkReachabilityStatusNotReachable:
default:
// -- Not reachable -- //
// -- Do your stuff for internet connection not available -- //
NSLog(@"Not Reachable");
break;
}
}
다음은 도달 가능성을 사용하지 않고 Swift를 사용하여 연결을 확인하는 좋은 솔루션입니다. 이 블로그 에서 찾았습니다 .
Network.swift
예를 들어 프로젝트에 새 Swift 파일을 만듭니다 . 이 코드를 해당 파일에 붙여 넣으십시오.
import Foundation
public class Network {
class func isConnectedToNetwork()->Bool{
var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
var response: NSURLResponse?
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
Status = true
}
}
return Status
}
}
그런 다음 다음을 사용하여 프로젝트 어디에서나 연결을 확인할 수 있습니다.
if Network.isConnectedToNetwork() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
편집 : 네트워크 URL에는 작동하지 않습니다 (댓글 참조)
iOS 5부터 새로운 NSURL 인스턴스 메소드가 있습니다.
- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error
관심있는 웹 사이트 또는 apple.com을 가리 킵니다. 인터넷이 기기에서 작동하는지 확인하기위한 새로운 단선 전화라고 생각합니다.
또한 사용 가능한 인터넷 확인 옵션에 만족하지 못했습니다 (왜 이것이 기본 API가 아니십니까?!?!)
내 자신의 문제는 장치가 라우터에 연결되어 있지만 라우터가 인터넷에 연결되어 있지 않은 경우 100 % 패킷 손실과 관련이 있습니다. 도달 가능성과 다른 사람들은 나이가 들게됩니다. 비동기 타임 아웃을 추가하여 유틸리티 단일 클래스를 처리했습니다. 내 앱에서 잘 작동합니다. 도움이 되길 바랍니다. github의 링크는 다음과 같습니다.
https://github.com/fareast555/TFInternetChecker
(iOS) Xcode 8.2, Swift 3.0에서 인터넷 연결 사용 가능 여부 확인
네트워크 가용성을 확인하는 간단한 방법입니다. 나는 그것을 Swift 2.0과 여기에서 최종 코드로 번역했습니다. 기존 Apple Reachability 클래스 및 기타 타사 라이브러리는 너무 복잡하여 Swift로 번역하기가 어려웠습니다.
이것은 3G 및 WiFi 연결 모두에서 작동합니다.
"SystemConfiguration.framework"를 프로젝트 빌더에 추가하는 것을 잊지 마십시오.
//Create new swift class file Reachability in your project.
import SystemConfiguration
public class Reachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability! , &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
}
// Check network connectivity from anywhere in project by using this code.
if Reachability.isConnectedToNetwork() == true {
print("Internet connection OK")
} else {
print("Internet connection FAILED")
}
tonymillion에서 영감을 얻은 Apple Reachability for Swift를 클로저로 다시 작성 : https://github.com/ashleymills/Reachability.swift
파일
Reachability.swift
을 프로젝트에 놓으십시오 . 또는 CocoaPods 또는 Carthage를 사용 하십시오- 프로젝트 README 의 설치 섹션을 참조하십시오 .네트워크 연결에 대한 알림 받기 :
//declare this property where it won't go out of scope relative to your listener let reachability = Reachability()! reachability.whenReachable = { reachability in if reachability.isReachableViaWiFi { 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") }
알림 중지
reachability.stopNotifier()
알라모 파이어
모든 RESTful API에 Alamofire 를 이미 사용하고 있다면 여기에서 혜택을 누릴 수 있습니다.
앱에 다음 클래스를 추가 MNNetworkUtils.main.isConnected()
하고 연결되어 있는지 여부에 대한 부울을 얻기 위해 호출 할 수 있습니다.
#import Alamofire
class MNNetworkUtils {
static let main = MNNetworkUtils()
init() {
manager = NetworkReachabilityManager(host: "google.com")
listenForReachability()
}
private let manager: NetworkReachabilityManager?
private var reachable: Bool = false
private func listenForReachability() {
self.manager?.listener = { [unowned self] status in
switch status {
case .notReachable:
self.reachable = false
case .reachable(_), .unknown:
self.reachable = true
}
}
self.manager?.startListening()
}
func isConnected() -> Bool {
return reachable
}
}
이것은 싱글턴 클래스입니다. 사용자가 네트워크를 연결하거나 연결을 끊을 때마다 on singleton 초기화를 self.reachable
수신하기 때문에 네트워크 가 true / false로 올바르게 재정의 됩니다 NetworkReachabilityManager
.
또한 연결 가능성을 모니터링하려면 호스트를 제공해야합니다. 현재는 필요 google.com
에 따라 다른 호스트 나 다른 호스트로 자유롭게 변경할 수 있습니다.
참고 URL : https://stackoverflow.com/questions/8812459/easiest-way-to-detect-internet-connection-on-ios
'Programing' 카테고리의 다른 글
ngRepeat 사용시 표시되는 결과 수 제한 (0) | 2020.06.14 |
---|---|
Windows 배치 파일에서 무한 루프를 만드는 방법은 무엇입니까? (0) | 2020.06.14 |
isKindOfClass와 isMemberOfClass의 iOS 차이점 (0) | 2020.06.14 |
동일한 div에서 두 버튼 사이에 공백을 어떻게 만들 수 있습니까? (0) | 2020.06.14 |
ASP.NET Core RC2 웹 API에서 HTTP 500을 반환하는 방법? (0) | 2020.06.14 |