Pertanyaan Bagaimana cara memeriksa koneksi internet aktif di iOS atau macOS?


Saya ingin memeriksa apakah saya memiliki koneksi Internet di iOS menggunakan Cocoa Touch perpustakaan atau di macOS menggunakan Biji cokelat perpustakaan.

Saya datang dengan cara melakukan ini menggunakan NSURL. Cara yang saya lakukan tampaknya agak tidak dapat diandalkan (karena bahkan Google dapat suatu hari nanti jatuh dan mengandalkan pihak ketiga tampak buruk), dan sementara saya dapat memeriksa untuk melihat tanggapan dari beberapa situs web lain jika Google tidak merespons, memang tampak sia-sia dan overhead yang tidak perlu pada aplikasi saya.

- (BOOL) connectedToInternet
{
    NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
    return ( URLString != NULL ) ? YES : NO;
}

Apa yang saya lakukan buruk, (belum lagi stringWithContentsOfURL sudah ditinggalkan di iOS 3.0 dan macOS 10.4) dan jika ya, apa cara yang lebih baik untuk mencapai ini?


1223
2017-07-05 08:45


asal


Jawaban:


Penting: Cek ini seharusnya selalu dilakukan secara asynchronous. Sebagian besar jawaban di bawah ini sinkron jadi berhati-hatilah jika tidak Anda akan membekukan aplikasi Anda.


Cepat

1) Instal melalui CocoaPods atau Carthage: https://github.com/ashleymills/Reachability.swift

2) Uji reachability via closures

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")
}

Objective-C

1) Tambahkan SystemConfiguration kerangka kerja untuk proyek tetapi jangan khawatir tentang memasukkannya ke mana saja

2) Tambahkan versi Tony Million dari Reachability.h dan Reachability.m ke proyek (ditemukan di sini: https://github.com/tonymillion/Reachability)

3) Perbarui bagian antarmuka

#import "Reachability.h"

// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
    Reachability *internetReachableFoo;
}
@end

4) Lalu terapkan metode ini dalam file .m dari pengontrol tampilan Anda yang dapat Anda hubungi

// 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];
}

Catatan penting: Itu Reachability kelas adalah salah satu kelas yang paling banyak digunakan dalam proyek sehingga Anda mungkin mengalami konflik penamaan dengan proyek lain. Jika ini terjadi, Anda harus mengganti nama salah satu pasangan Reachability.h dan Reachability.m file ke sesuatu yang lain untuk menyelesaikan masalah.

catatan: Domain yang Anda gunakan tidak masalah. Ini hanya menguji gerbang ke domain mana pun.


1220
2017-08-29 23:58



Saya suka menjaga hal-hal sederhana. Cara saya melakukan ini adalah:

//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;
}

Kemudian, saya menggunakan ini setiap kali saya ingin melihat apakah saya memiliki koneksi:

if (![self connected]) {
    // Not connected
} else {
    // Connected. Do some Internet stuff
}

Metode ini tidak menunggu perubahan status jaringan untuk melakukan hal-hal. Itu hanya menguji status saat Anda memintanya.


303
2017-08-26 13:34



Menggunakan kode Reachability Apple, saya membuat fungsi yang akan memeriksa ini dengan benar tanpa Anda harus menyertakan kelas apa pun.

Sertakan SystemConfiguration.framework dalam proyek Anda.

Buat beberapa impor:

#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>

Sekarang panggil saja fungsi ini:

/*
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;
}

Dan itu iOS 5 diuji untuk Anda.


143
2017-10-28 20:37



Ini adalah jawaban yang benar, tetapi sekarang sudah usang karena Anda harus berlangganan notifikasi untuk dapat dijangkau sebagai gantinya. Metode ini memeriksa serentak:


Anda dapat menggunakan kelas Reachability Apple. Ini juga akan memungkinkan Anda untuk memeriksa apakah Wi-Fi diaktifkan:

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) { }

Kelas Reachability tidak dikirimkan dengan SDK, melainkan bagian dari aplikasi sampel Apple ini. Cukup unduh, dan salin Reachability.h / m ke proyek Anda. Juga, Anda harus menambahkan kerangka SystemConfiguration ke proyek Anda.


118
2017-07-05 10:58



Inilah jawaban yang sangat sederhana:

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 harus mengarah ke situs web yang sangat kecil. Saya menggunakan situs web seluler Google di sini, tetapi jika saya memiliki server web tepercaya yang akan saya unggah file kecil dengan hanya satu karakter di dalamnya untuk kecepatan maksimum.

Jika memeriksa apakah perangkat itu entah bagaimana terhubung ke Internet adalah semua yang ingin Anda lakukan, saya pasti akan merekomendasikan menggunakan solusi sederhana ini. Jika Anda perlu mengetahui bagaimana pengguna terhubung, menggunakan Reachability adalah cara yang tepat.

Hati-hati: Ini akan memblokir secara singkat thread Anda saat memuat situs web. Dalam kasus saya, ini bukan masalah, tetapi Anda harus mempertimbangkan ini (kredit untuk Brad untuk menunjukkan hal ini).


78
2018-05-14 22:25



Di sini adalah bagaimana saya melakukannya di aplikasi saya: Meskipun kode tanggapan status 200 tidak menjamin apa pun, itu cukup stabil untuk saya. Ini tidak membutuhkan banyak pemuatan karena jawaban NSData diposting di sini, karena saya hanya memeriksa respons HEAD.

Tukar Kode

func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    let url = NSURL(string: "http://www.appleiphonecell.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 Apple's region universal URL reachable
        }
        else
        {
            // No "Internet" aka Apple's region universal URL un-reachable
        }
    })
}

Kode Objective-C

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.appleiphonecell.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 Apple's region universal URL reachable
         }
         else
         {
             // No "Internet" aka Apple's region universal URL un-reachable
         }
    }];
}

70
2017-11-30 03:26



Persediaan Apple Kode sampel untuk memeriksa berbagai jenis ketersediaan jaringan. Atau ada contoh di buku masak pengembang iPhone.

catatan: Silakan lihat komentar @ KHG pada jawaban ini mengenai penggunaan kode reachability Apple.


54
2017-07-05 08:59



Anda bisa menggunakannya Reachability oleh  (Tersedia disini).

#import "Reachability.h"

- (BOOL)networkConnection {
    return [[Reachability reachabilityWithHostName:@"www.google.com"] currentReachabilityStatus];
}

if ([self networkConnection] == NotReachable) { /* No Network */ } else { /* Network */ } //Use ReachableViaWiFi / ReachableViaWWAN to get the type of connection.

43
2018-04-25 12:20



Apple menyediakan contoh aplikasi yang melakukan hal ini:

Reachability


39
2017-07-05 08:58



Hanya kelas Reachability yang telah diperbarui. Anda sekarang dapat menggunakan:

Reachability* reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if (remoteHostStatus == NotReachable) { NSLog(@"not reachable");}
else if (remoteHostStatus == ReachableViaWWAN) { NSLog(@"reachable via wwan");}
else if (remoteHostStatus == ReachableViaWiFi) { NSLog(@"reachable via wifi");}

32
2017-08-27 09:41