iOS에서 인터넷 연결을 감지하는 가장 쉬운 방법은 무엇입니까?
저는 이 질문이 다른 많은 사람들의 속임수처럼 보일 것이라는 것을 알고 있지만, 저는 여기서 간단한 사례가 잘 설명되어 있다고 생각하지 않습니다. 및 에서 Android를 통해 및온것으로다에음요합통청을니해다배경서▁black요▁▁coming다청니합해ground,▁making다,▁requests통음▁from▁black을▁an▁and및▁android로berry▁android.HTTPUrlConnection
사용 가능한 연결이 없는 경우 즉시 실패합니다.이건 완전히 제정신인 행동인 것 같고, 그리고 저는 그것을 발견하고 놀랐습니다.NSURLConnection
에뮬레이트하지 .iOS에서는 그것을 에뮬레이트하지 않았습니다.
(및한 다른이 Apple(애플)을 제공하는 있습니다.Reachability
네트워크 상태를 결정하는 데 도움이 되는 클래스입니다.저는 처음에 이것을 보고 기뻤고 그런 것을 볼 것이라고 전적으로 기대했습니다.bool isNetworkAvailable()
하지만 놀랍게도 알림 등록과 콜백이 필요한 복잡한 시스템과 불필요해 보이는 많은 세부 사항을 발견했습니다.더 좋은 방법이 있을 겁니다.
내 앱은 이미 연결이 없는 것을 포함하여 연결 실패를 정상적으로 처리합니다.사용자에게 오류가 통지되고 앱이 이동합니다.
따라서 제 요구 사항은 간단합니다. 모든 HTTP 요청 전에 호출하여 요청을 실제로 보내야 하는지 여부를 결정할 수 있는 단일 동기 기능입니다.설정할 필요 없이 부울만 반환하는 것이 이상적입니다.
iOS에서는 정말 이것이 불가능합니까?
저는 조금 더 조사를 했고 더 최신 솔루션으로 답변을 업데이트하고 있습니다.이미 보셨는지 모르겠지만 애플에서 제공한 좋은 샘플 코드가 있습니다.
여기에서 샘플 코드 다운로드
프로젝트에 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");
}
@벤자민 피에트:프로젝트에 SystemConfiguration.framework를 추가하는 것을 잊지 마십시오.
이 스레드가 이러한 유형의 질문에 대한 최고의 구글 결과이기 때문에, 저는 제게 맞는 솔루션을 제공할 것이라고 생각했습니다.저는 이미 AF네트워킹을 사용하고 있었지만, 제 프로젝트 중간까지 AF네트워킹으로 이 작업을 수행하는 방법을 찾지 못했습니다.
당신이 원하는 것은 AF Networking Reachability Manager입니다.
// -- 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의 와이파이를 켜고 끕니다.
업데이트:
결국 저는 스레드/비동기 콜백을 사용하여 메인 스레드를 차단하지 않도록 했습니다. 그리고 캐시된 결과를 사용할 수 있도록 정기적으로 다시 테스트했습니다. 데이터 연결을 불필요하게 열어 두는 것은 피해야 합니다.
@thunk가 설명한 것처럼, Apple 자체가 사용하는 더 나은 URL이 있습니다.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
누군가가 이전에 이것을 간단하고 재사용 가능한 방법으로 해결했습니다.
편집: 또는.
코드를 추출하여 하나의 방법으로 넣었습니다. 다른 사람들에게 도움이 되기를 바랍니다.
#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;
}
만약 누군가가 그것이 유용하다고 생각한다면, 나는 여기에 swift2라고 쓰여질 수 있는 swift 버전의 답변을 쓰고 있습니다.
SampleCode에서 필요한 파일을 다운로드할 수 있습니다.
더하다Reachability.h
그리고.Reachability.m
프로젝트에 파일을 저장합니다.
는 이생성야합다니를 합니다.Bridging-Header.h
의 프로젝트에하지 않는 , 만약당프존않는면다지재하에,
의 용자내 에.Bridging-Header.h
line "file add this line:
#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
}
}
이게 도움이 될 것 같아요..
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
if([AFNetworkReachabilityManager sharedManager].isReachable)
{
NSLog(@"Network reachable");
}
else
{
NSLog(@"Network not reachable");
}
프로젝트에서 이미 AF 네트워킹을 구성한 경우에도 이를 시도할 수 있습니다.
-(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를 사용하여 연결을 확인하는 좋은 솔루션입니다.이 블로그에서 찾았습니다.
프로젝트에 다음과 같은 새 Swift 파일을 만듭니다.Network.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에서 인터넷 연결 가능 여부 확인
이것은 네트워크 가용성을 확인하는 간단한 방법입니다.스위프트 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")
}
수십억 달러에 영감을 받아 Swift로 다시 작성된 Apple Reachability를 대체합니다. https://github.com/ashleymills/Reachability.swift
파일을 삭제
Reachability.swift
당신의 프로젝트에.또는 코코아 포드 또는 카르타고를 사용하십시오. 프로젝트 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
}
}
이것은 싱글톤 수업입니다.매번 사용자가 네트워크를 연결하거나 연결을 끊으면 네트워크가 오버라이드됩니다.self.reachable
정확하게 참/거짓입니다, 왜냐하면 우리는 듣기 시작하기 때문입니다.NetworkReachabilityManager
싱글톤 초기화 시.
도달 가능성을 모니터링하기 , 저는 또한연가결모면려현하재사합중제다니호공을 사용하고 .google.com
필요한 경우 다른 호스트 또는 호스트 중 하나로 자유롭게 변경할 수 있습니다.
언급URL : https://stackoverflow.com/questions/8812459/easiest-way-to-detect-internet-connection-on-ios
'programing' 카테고리의 다른 글
텍스트 파일을 단일 문자열로 가져오기 (0) | 2023.06.26 |
---|---|
"일시 중단됨" 상태와 디스크 높음 상태는 무엇입니까?IO는 sp_who2에서 온 것입니까? (0) | 2023.06.26 |
Node.js MSSQL tedius 연결 오류: localhost: 1433에 연결하지 못했습니다. - connect ECONFUSED (0) | 2023.06.26 |
SQL Server 윈도우즈 모드에서 혼합 모드(SQL Server 2008)로 변경하는 방법은 무엇입니까? (0) | 2023.06.26 |
Android.os의 ANR.MessageQueue.nativePollOnce (0) | 2023.06.26 |