วิธีที่ง่ายที่สุดในการตรวจหาการเชื่อมต่ออินเทอร์เน็ตบน iOS?


147

ฉันรู้ว่าคำถามนี้จะดูเหมือนว่าเป็นเรื่องล่อแหลมของคนอื่น ๆ แต่ฉันไม่รู้สึกว่ากรณีง่ายอธิบายไว้ที่นี่ มาจากพื้นหลังของ Android และ BlackBerry ทำให้การร้องขอผ่านHTTPUrlConnectionล้มเหลวทันทีหากไม่มีการเชื่อมต่อ ดูเหมือนว่าพฤติกรรมที่มีสติอย่างสมบูรณ์และฉันรู้สึกประหลาดใจที่พบว่าNSURLConnectionใน iOS ไม่ได้เลียนแบบ

ฉันเข้าใจว่า Apple (และผู้อื่นที่ขยายเวลา) จัดเตรียมReachabilityคลาสเพื่อช่วยในการพิจารณาสถานะเครือข่าย ฉันมีความสุขที่ได้เห็นสิ่งนี้เป็นครั้งแรกและคาดหวังอย่างเต็มที่ว่าจะเห็นอะไรบางอย่างbool isNetworkAvailable()แต่แทนที่จะแปลกใจที่ฉันพบว่าระบบที่ซับซ้อนซึ่งต้องมีการลงทะเบียนการแจ้งเตือนและการโทรกลับและรายละเอียดที่ไม่จำเป็น จะต้องมีวิธีที่ดีกว่า

แอพของฉันจัดการการเชื่อมต่อที่ล้มเหลวได้อย่างงดงาม ผู้ใช้จะได้รับแจ้งถึงความล้มเหลวและแอปจะดำเนินการต่อ

ดังนั้นความต้องการของฉันจึงง่าย: ฟังก์ชั่นเดียวแบบซิงโครนัสฉันสามารถโทรหาก่อนที่จะร้องขอ HTTP ทั้งหมดเพื่อตรวจสอบว่าฉันควรรำคาญที่จะส่งคำขอจริงหรือไม่ เป็นการดีที่มันไม่จำเป็นต้องตั้งค่าและเพียงแค่ส่งกลับบูลีน

สิ่งนี้เป็นไปไม่ได้บน iOS หรือเปล่า



คุณไม่ควรเรียกวิธีการเข้าถึงเครือข่ายแบบซิงโครนัสก่อนคำขอ HTTP ทุกครั้ง เป็นเรื่องที่ค่อนข้างบ้าที่จะทำเช่นนั้นเว้นแต่ว่าความสามารถในการเข้าถึงได้แบบอะซิงโครนัสบอกคุณว่ามีการเปลี่ยนแปลงเงื่อนไขของเครือข่ายและจากนั้นคุณสามารถเลือกที่จะไม่ส่งคำขอ HTTP นี่เป็นเหตุผลหมดเวลาทั้งหมดที่มีอยู่ (และคุณควรจัดการกับสถานการณ์นั้นอย่างสง่างาม) ดูลิงค์ด้านบนสำหรับวิธี async
iwasrobbed

คำตอบ:


251

ฉันทำวิจัยเพิ่มอีกเล็กน้อยและฉันกำลังปรับปรุงคำตอบของฉันด้วยโซลูชันที่เป็นปัจจุบันมากขึ้น ฉันไม่แน่ใจว่าคุณได้ดูไปแล้ว แต่มีรหัสตัวอย่างที่ดีจาก 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 ในโครงการของคุณ


46
อย่าลืมเพิ่ม SystemConfiguration.framework ในโครงการของคุณ
Benjamin Piette

1
@chandru มันได้ผล นี่เป็นวิธีที่ง่ายที่สุดและมีประสิทธิภาพที่สุดที่ฉันเห็นในการตรวจสอบการเชื่อมต่อเครือข่าย ง่ายและสะดวก!
S1U

3
ระวังด้วยนะ ฉันพบว่ามันใช้งานไม่ได้อย่างน่าเชื่อถือเมื่อเครือข่ายคืนค่าอย่างน้อยในเครื่องจำลอง ฉันเปิดตัวพร้อม WiFi ปิดและรายงานเครือข่ายไม่ถูกต้อง แต่จากนั้นฉันเปิด wifi อีกครั้งและ SCNetworkReachabilityGetFlags ยังคงส่งคืนค่า 0 แม้ว่าเคียวรีเครือข่ายจริงจะทำงานได้ดี
Joe Strout

2
ฉันเชื่อว่าคำตอบของฉันด้านล่าง ( stackoverflow.com/a/26593728/557362 ) ต้องการงานน้อยลง (ไม่ต้องดาวน์โหลดไฟล์อื่น ๆ ) แต่นั่นเป็นเพียงความคิดเห็นของฉัน
GilesDMiddleton

3
โปรดทราบว่านี่จะบอกคุณว่าการเชื่อมต่อกับโฮสต์ที่เฉพาะเจาะจงนั้นสามารถกำหนดเส้นทางได้หรือไม่ ไม่ได้หมายความว่าคุณสามารถเชื่อมต่อได้จริง ตัวอย่าง: คุณเชื่อมต่อ wifi ของ iPhone กับ wifi ของกล้อง Wifi เชื่อมต่อกับเกตเวย์เริ่มต้น: โฮสต์ทั้งหมดจะรายงานว่าสามารถเข้าถึงได้ แต่จริงๆแล้วไม่ใช่ - กล้องเป็นการเชื่อมต่อแบบสิ้นตาย
xaphod

45

เมื่อเห็นว่ากระทู้นี้เป็นผลการค้นหาอันดับต้น ๆ ของ Google สำหรับคำถามประเภทนี้ฉันคิดว่าฉันจะให้โซลูชันที่เหมาะกับฉัน ฉันใช้เครือข่าย AFNอยู่แล้วแต่การค้นหาไม่ได้เปิดเผยวิธีการทำงานนี้ให้สำเร็จด้วย 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;
}

3
ฉัน upvoted สำหรับการนำAFNetworkReachabilityManagerเข้าสู่แสงสว่าง!
Selvin

สำหรับผู้ที่ไม่ชัดเจนในทันที: AFNetworking เป็นห้องสมุดบุคคลที่สาม
arlomedia

1
ความสามารถในการเข้าถึงเครือข่ายเป็นเครื่องมือวินิจฉัยที่สามารถใช้เพื่อทำความเข้าใจว่าทำไมคำขออาจล้มเหลว ไม่ควรใช้เพื่อพิจารณาว่าจะทำการร้องขอหรือไม่ - นั่นคือสิ่งที่เอกสารพูดว่า
Nosov Pavel

AFNetworkReachabilityManager.reachableไม่ทำการตรวจสอบแบบซิงโครนัสใด ๆ มันกลับตรรกะหรือของและreachableViaWWAN reachableViaWifi
jdolan

40

ขออภัยที่ตอบช้าเกินไป แต่ฉันหวังว่าคำตอบนี้จะช่วยใครบางคนในอนาคต

ต่อไปนี้เป็นข้อมูลโค้ด 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
    }

3
ทำงานได้ดีกว่า Apple Reachability แต่ตามเอกสาร gethostbyname ล้าสมัยและคุณควรใช้ getaddrinfo: struct addrinfo * res = NULL; int s = getaddrinfo ("apple.com", NULL, NULL, & res); bool network_ok = (s == 0 && res! = NULL); freeaddrinfo (Res);
Tertium

1
แม้ว่าจะเป็นเรื่องปกติที่จะใช้ google.com เพื่อตรวจสอบความพร้อมใช้งานอินเทอร์เน็ต แต่ก็น่าสังเกตว่ามันถูกบล็อกในบางประเทศ ตัวเลือกที่ดีกว่าคือโดเมนจาก บริษัท "เป็นมิตรกับรัฐบาล" เช่น yahoo.com หรือ microsoft.com
เรนต์

8
@ Laurent: ตัวเลือกที่ดีที่สุดคือใช้ที่อยู่เซิร์ฟเวอร์ที่คุณต้องการขอข้อมูล google.com ตรงนี้เป็นเพียงตัวอย่าง
แจกจ่าย

7
นี่เป็นเพียงการค้นหา DNS หรือไม่ ถ้าเป็นเช่นนั้นผลลัพธ์ DNS ที่แคชไว้อาจส่งผลให้ฟังก์ชันเชื่อผิดว่าเครือข่ายพร้อมใช้งานหรือไม่
Stephen Moore

2
@amar การทำงานแบบวนซ้ำจะใช้ข้อมูลไร้สายคุณไม่ต้องการทำเช่นนั้น
ความหมาย - เรื่อง

31

ขณะนี้ฉันใช้วิธีการซิงโครนัสอย่างง่ายซึ่งไม่ต้องการไฟล์เพิ่มเติมในโครงการหรือผู้รับมอบสิทธิ์ของคุณ

นำเข้า:

#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.
}

หากคุณกำลังทำการทดสอบในเครื่องจำลองให้เปิดและปิด wifi ของ Mac เนื่องจากปรากฏว่าเครื่องจำลองจะไม่สนใจการตั้งค่าโทรศัพท์

ปรับปรุง:

  1. ในที่สุดฉันใช้การเรียกกลับเธรด / อะซิงโครนัสเพื่อหลีกเลี่ยงการบล็อกเธรดหลัก และทำการทดสอบซ้ำเป็นประจำเพื่อให้ฉันสามารถใช้ผลการแคช - แม้ว่าคุณควรหลีกเลี่ยงการเปิดการเชื่อมต่อข้อมูลโดยไม่จำเป็น

  2. ตามที่ @thunk อธิบายไว้มี URL ที่ดีกว่าที่จะใช้ซึ่ง Apple เองใช้ http://cadinc.com/blog/why-your-apple-ios-7-device-wont-connect-to-the-wifi-network


1
ขอบคุณและเหมือนกับคนอื่น ๆ ส่วนใหญ่ในหัวข้อนี้: อย่าลืมเพิ่ม SystemConfiguration.framework ในโครงการของคุณ
eselk

1
แปลกในโครงการ Xcode ของฉันฉันไม่ต้องเพิ่ม SystemConfiguration.framework ฉันมี SpriteKit, UIKit, StoreKit, Foundation และ CoreGraphics แต่ไม่ใช่ SystemConfiguration .... มีการรวมบางอย่างโดยนัยหรือไม่?
GilesDMiddleton

3
สิ่งนี้ใช้ได้สำหรับฉัน แต่เมื่อฉันวิ่งเมื่อเชื่อมต่อกับเครือข่าย Wi-Fi ที่ไม่มีการเชื่อมต่ออินเทอร์เน็ตมันจะล็อค UI ของฉันประมาณ 30 วินาที จำเป็นต้องใช้วิธีอะซิงโครนัสในสถานการณ์นั้น
arlomedia

2
www.apple.comเป็นเว็บไซต์ใหญ่ ... ตัวเลือกที่ดีกว่าจะได้www.google.com
Fahim Parkar

2
คำตอบที่ยอดเยี่ยม! ข้อเสนอแนะหนึ่งข้อ: URL ทดสอบwww.appleiphonecell.comควรใช้อย่างเคร่งครัดเพื่อจุดประสงค์นี้และเห็นได้ชัดว่าไม่ได้ถูกบล็อกในประเทศจีน
Thunk

11

เป็นไปได้และมันง่ายมากถ้าคุณดูเมื่อเสร็จสิ้นการนำไปใช้ซึ่งเป็นอีกครั้ง - ง่ายมากเนื่องจากรายการเดียวที่คุณต้องการคือตัวแปรบูลีนสองตัว: การเข้าถึงอินเทอร์เน็ตและการเข้าถึงโฮสต์ (คุณมักต้องการมากกว่าหนึ่งรายการ) ) เมื่อคุณรวบรวมคลาสผู้ช่วยที่สามารถกำหนดสถานะการเชื่อมต่อได้คุณจะไม่สนใจการใช้งานที่จำเป็นสำหรับการรู้ขั้นตอนเหล่านี้อีก

ตัวอย่าง:

#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

6

มีคนแก้ไขปัญหานี้ด้วยวิธีที่ง่ายและใช้ซ้ำได้ก่อนหน้านี้DDGReachability.

แก้ไข: tonymillion/Reachabilityหรือ


4

ฉันแยกรหัสและใส่เป็นวิธีการเดียวหวังว่าจะช่วยให้ผู้อื่น

#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;


}

[A] คุณดึงรหัสนี้มาจากที่ใด คุณสามารถโพสต์ลิงค์ไปยังแหล่งที่มาได้หรือไม่? [B] ขอบคุณมากสำหรับงานสกัดของคุณ! สิ่งที่ฉันต้องการ ฉันกำลังจะทำงานนี้ด้วยตัวเอง
Basil Bourque

ดังนั้นดูเหมือนว่านี่เป็นคำตอบเดียวที่ไม่ได้ตรวจสอบเซิร์ฟเวอร์ระยะไกลใด ๆ
Jasper

สำหรับผู้อื่นที่ทดสอบสิ่งนี้ใน MacOS โปรดทราบว่า kSCNetworkReachabilityFlagsIsWWAN นั้นใช้สำหรับ OS_IPHONE ไม่ใช่ macOS
GeoffCoope

4

ฉันกำลังเขียนคำตอบที่ยอมรับได้อย่างรวดเร็วที่นี่กรณีถ้ามีคนพบว่ามันมีประโยชน์รหัสก็เขียนอย่างรวดเร็ว 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
    }

}

3

ฉันคิดว่านี่จะช่วยได้ ..

[[AFNetworkReachabilityManager sharedManager] startMonitoring];

if([AFNetworkReachabilityManager sharedManager].isReachable)
{
    NSLog(@"Network reachable");
}
else
{   
   NSLog(@"Network not reachable");
}

สิ่งนี้ไม่ทำงานหากอินเตอร์เฟสเครือข่ายไม่เปลี่ยนแปลงและการเชื่อมต่ออินเทอร์เน็ตขาดหายไป
Pratik Somaiya

2

คุณอาจลองอันนี้ถ้าคุณได้กำหนดค่า 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;
}
}

1

นี่เป็นทางออกที่ดีสำหรับการตรวจสอบการเชื่อมต่อโดยใช้ 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")
}

0

แก้ไข: สิ่งนี้จะไม่ทำงานกับ URL เครือข่าย (ดูความคิดเห็น)

ตั้งแต่ iOS 5 มีวิธีอินสแตนซ์ NSURL ใหม่:

- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error

ชี้ไปที่เว็บไซต์ที่คุณสนใจหรือชี้ไปที่ apple.com; ฉันคิดว่ามันเป็นการโทรครั้งเดียวแบบใหม่เพื่อดูว่าอินเทอร์เน็ตทำงานบนอุปกรณ์ของคุณหรือไม่


ที่จริงแล้วในการทดสอบของฉันเองมันจะส่งกลับค่าเท็จเสมอ เอกสารระบุว่าเป็นกรณีสำหรับ 4.x แต่ใน 5+ ควรใช้งานได้ YMMV
SG1

สิ่งนี้ดูเหมือนจะไม่ทำงานสำหรับสถานการณ์ที่คุณกำลังมองหา ดูstackoverflow.com/questions/9266154/…
Micah Hainline

7
ใช้สำหรับ URL ไฟล์ไม่ใช่ URL อินเทอร์เน็ต
วิกเตอร์บ็อกแดน

0

ฉันไม่พอใจกับตัวเลือกการตรวจสอบอินเทอร์เน็ตที่มีอยู่ (เพราะเหตุใดนี่จึงไม่ใช่ API ดั้งเดิม!!?!)

ปัญหาของฉันคือแพ็คเก็ตสูญหาย 100% - เมื่ออุปกรณ์เชื่อมต่อกับเราเตอร์ แต่เราเตอร์ไม่ได้เชื่อมต่อกับอินเทอร์เน็ต ความสามารถในการเข้าถึงและอื่น ๆ จะแขวนอยู่นาน ฉันสร้างคลาสยูทิลิตี้เดี่ยวเพื่อจัดการกับสิ่งนั้นโดยการเพิ่มการหมดเวลา asynch มันทำงานได้ดีในแอพของฉัน หวังว่ามันจะช่วย นี่คือลิงค์ของ GitHub:

https://github.com/fareast555/TFInternetChecker


0

ตรวจสอบความพร้อมในการเชื่อมต่ออินเทอร์เน็ตใน (Xcode 8.2, Swift 3.0)

นี่เป็นวิธีง่าย ๆ ในการตรวจสอบความพร้อมของเครือข่าย ฉันจัดการแปลมันเป็น Swift 2.0 และนี่คือรหัสสุดท้าย คลาสการเข้าถึงของ Apple ที่มีอยู่และห้องสมุดบุคคลที่สามอื่น ๆ ดูเหมือนจะซับซ้อนเกินกว่าจะแปลเป็น 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")
}

ด้วย Xcode รุ่น 7.2 (7C68) รหัสนี้มีข้อผิดพลาดของคอมไพเลอร์
Daniel

@Daniel ขอบคุณสำหรับปัญหาการชี้เนื่องจากตัวชี้ที่ไม่ปลอดภัยเนื่องจาก Swift 2 / Xcode กำลังอัปเดตไวยากรณ์อยู่ที่นั่นเราควรติดตามพวกเขา ฉันได้รับการปรับปรุงรหัสสำหรับเดียวกัน ty;)
ViJay Avhad

หากคุณเชื่อมต่อกับ Wi-Fi แต่ไม่สามารถเชื่อมต่ออินเทอร์เน็ตได้ (เปิดหน้า Google) ก็จะยังคงให้ผลตอบแทนที่แท้จริงสำหรับการเข้าถึง มันผิด.
Arildo Junior

0

ทดแทนการเข้าถึงของ Apple เขียนขึ้นใหม่ใน Swift ด้วยการปิดโดยได้รับแรงบันดาลใจจาก tonymillion: https://github.com/ashleymills/Reachability.swift

  1. วางไฟล์Reachability.swiftลงในโครงการของคุณ หรือใช้CocoaPodsหรือCarthage - ดูส่วนการติดตั้งของ README ของโครงการ

  2. รับการแจ้งเตือนเกี่ยวกับการเชื่อมต่อเครือข่าย:

    //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()

0

Alamofire

หากคุณใช้Alamofireแล้วสำหรับ RESTful Api ทั้งหมดนี่คือสิ่งที่คุณสามารถได้รับจากสิ่งนั้น

คุณสามารถเพิ่มคลาสต่อไปนี้ลงในแอพของคุณและโทรหา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ความรู้สึกอิสระที่จะเปลี่ยนเป็นโฮสต์อื่นหรือหนึ่งในโฮสต์ของคุณหากจำเป็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.