स्विफ्ट में इंटरनेट कनेक्शन की उपलब्धता की जाँच करें


107

क्या यह जांचने का कोई तरीका है कि क्या स्विफ्ट का उपयोग करके इंटरनेट कनेक्शन उपलब्ध है?

मुझे पता है कि ऐसा करने के लिए कई तीसरे पक्ष के पुस्तकालय हैं लेकिन वे सभी उद्देश्य-सी में लिखे गए हैं। मैं एक स्विफ्ट विकल्प की तलाश कर रहा हूं।


5
स्विफ्ट के विशाल लाभों में से एक यह है कि यह उद्देश्य-सी (और इस तरह के पुस्तकालयों) के साथ अच्छी तरह से एकीकृत करता है।
user2864740

वास्तव में। मौजूदा पुस्तकालयों में से एक का उपयोग करने में आपको क्या समस्याएँ हैं? स्विफ्ट से ऑब्जेक्टिव सी लाइब्रेरी का उपयोग करना बहुत सरल है, और यदि आप ऐसा नहीं कर सकते हैं तो स्विफ्ट में किसी भी तरह का ऐप लिखना आपके लिए बेहद मुश्किल साबित होगा।
मैट गिब्सन

1
@MattGibson लगभग सभी चीजें जो आप ओब्जेक्ट में कर सकते हैं, स्विफ्ट में रिश्तेदार आसानी से कर सकते हैं। दी गई, इस मामले में कुछ अतिरिक्त लाइनें होंगी लेकिन फिर भी "बेहद मुश्किल" से दूर
बायरन कोएत्सी

@ByronCoetsee I में AppKit जैसी लाइब्रेरी का उपयोग करना शामिल था, आदि-मेरी बात यह है कि आपको स्विफ्ट में कुछ भी उपयोगी लिखने के लिए ऑब्जेक्टिव सी लाइब्रेरी के साथ बातचीत करने की आवश्यकता होगी।
मैट गिब्सन

आलमोफायर उत्तर देखें - stackoverflow.com/a/46562290/7576100
जैक

जवाबों:


227

जैसा कि टिप्पणियों में उल्लेख किया गया है, हालांकि स्विफ्ट में उद्देश्य-सी पुस्तकालयों का उपयोग करना संभव है, मैं एक अधिक शुद्ध स्विफ्ट समाधान चाहता था। मौजूदा Apple रीचैबिलिटी क्लास और अन्य थर्ड पार्टी लाइब्रेरी मुझे स्विफ्ट में अनुवाद करने के लिए बहुत जटिल लग रहे थे। मैंने कुछ और जाना और मैं इस लेख पर आया, जो नेटवर्क उपलब्धता की जांच करने के लिए एक सरल विधि दिखाता है। मैं स्विफ्ट के लिए इसका अनुवाद करने के लिए तैयार हूं। मैंने कई झपट्टे मारे लेकिन स्टैकऑवरफ्लो से मार्टिन आर के लिए धन्यवाद , मैं उन्हें हल करने में कामयाब रहा और अंत में स्विफ्ट में एक व्यावहारिक समाधान प्राप्त किया। यहाँ कोड है।

import Foundation
import SystemConfiguration

public class Reachability {

    class func isConnectedToNetwork() -> Bool {

        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)

        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
        }

        var flags: SCNetworkReachabilityFlags = 0
        if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
            return false
        }

        let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

        return isReachable && !needsConnection
    }

}

स्विफ्ट के लिए> 3.0

public class Reachability {
    public func isConnectedToNetwork() -> Bool {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
        zeroAddress.sin_family = sa_family_t(AF_INET)

        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                SCNetworkReachabilityCreateWithAddress(nil, $0)
            }
        }) else {
            return false
        }

        var flags: SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return false
        }
        if flags.isEmpty {
            return false
        }

        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)

        return (isReachable && !needsConnection)
    }
}

यह 3 जी और वाईफाई कनेक्शन दोनों के लिए काम करता है। मैंने इसे एक कार्यकारी उदाहरण के साथ अपने GitHub पर भी अपलोड किया है ।


7
तेजी से प्रतिक्रिया के लिए धन्यवाद (कोई सज़ा नहीं)। MIT या Apache आदर्श होगी - धन्यवाद!
एंड्रयू एबलिंग

4
किया हुआ। इसे एमआईटी में बदल दिया।
Isuru

11
मुझे एक और मुद्दा मिला, अगर 3G चालू हो जाता है, लेकिन मेरे पास अधिक डेटा क्षमता नहीं isConnectedToNetworkहै, तो यह सच है, लेकिन मैं अपनी वेब सेवा को कॉल नहीं कर सकता
János

11
जैसा कि @Isuru ने कहा, यह stackoverflow.com/a/25623647/1187415 पर आधारित है , जिसे अब Swift 2 के लिए अपडेट किया गया है
मार्टिन आर

2
@ जेनोस: स्विफ्ट 2 के साथ अब एक अधिसूचना कॉलबैक की स्थापना संभव है, अपडेटेड उत्तर stackoverflow.com/a/27142665/1187415 देखें
मार्टिन आर

16

मैं आपको बेहतर तरीका देता हूं ...

आपको इस कोड के साथ एक क्लास बनाना होगा

 import Foundation
 public class Reachability {

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 Reachability.isConnectedToNetwork() == true {
     println("Internet connection OK")
} else {
     println("Internet connection FAILED")
}

बहुत आसान!

* यह तरीका विक्रम पोटे उत्तर पर आधारित है!


15
कृपया ध्यान रखें कि आपको इस विधि का उपयोग ऊपर दिए गए उपयोग में नहीं करना चाहिए । उन अनुप्रयोगों में जिन्हें निरंतर कनेक्टिविटी की आवश्यकता होती है, इस पद्धति की तरह एक प्रतिक्रिया जांचने से एप्लिकेशन को उन स्थितियों में लटका दिया जाएगा जहां आपकी इंटरनेट कनेक्टिविटी खराब है (यानी एज / जीपीआरएस पर)। कृपया इस समाधान का उपयोग न करें !!
इमरान अहमद

7
खराब रास्ता 1) सर्वर इव्री टाइम 2 के लिए अतिरिक्त हिट की जरूरत है) google.com भी डाउन हो सकता है
विजय सिंह राणा

2
1. हाँ, इस तरह से हर बार सर्वर को अतिरिक्त हिट की आवश्यकता होती है, लेकिन यह 100% गारंटी देता है कि इंटरनेट उपलब्ध है ... कई बार ऐसा होता है जब डिवाइस एक वाईफाई नेटवर्क से जुड़ा होता है, लेकिन इंटरनेट एक्सेस प्रदान नहीं करता है! इस स्थिति में, यह तरीका इंटरनेट तक पहुंच की कमी को निर्धारित करता है ... अन्य तरीके - नहीं! 2. आप google.com के बजाय अपने खुद के सर्वर का उपयोग कर सकते हैं ... यह मूल रूप से था ...
दिमित्री

1
गरीब समाधान, कनेक्शन हत्यारा।
गोखानकूट

2
gokhanakkurt, कृपया, एक और उपाय सुझाएं जो यह सुनिश्चित करता है कि इंटरनेट 100% पर काम करता है
दिमित्री

15

स्विफ्ट 3.1 के लिए (iOS 10.1)

यदि आप नेटवर्क-प्रकार (यानी WiFi या WWAN) के बीच अंतर करना चाहते हैं:

आप उपयोग कर सकते हैं:

func checkWiFi() -> Bool {

    let networkStatus = Reachability().connectionStatus()
    switch networkStatus {
    case .Unknown, .Offline:
        return false
    case .Online(.WWAN):
        print("Connected via WWAN")
        return true
    case .Online(.WiFi):
        print("Connected via WiFi")
        return true
    }
}

यहां संपूर्ण रीचैबिलिटी-क्लास है जो नेटवर्क-प्रकारों के बीच प्रतिष्ठित है:

import Foundation
import SystemConfiguration

import UIKit
import SystemConfiguration.CaptiveNetwork

public let ReachabilityStatusChangedNotification = "ReachabilityStatusChangedNotification"

public enum ReachabilityType: CustomStringConvertible {
    case WWAN
    case WiFi

    public var description: String {
        switch self {
        case .WWAN: return "WWAN"
        case .WiFi: return "WiFi"
        }
    }
}

public enum ReachabilityStatus: CustomStringConvertible  {
    case Offline
    case Online(ReachabilityType)
    case Unknown

    public var description: String {
        switch self {
        case .Offline: return "Offline"
        case .Online(let type): return "Online (\(type))"
        case .Unknown: return "Unknown"
        }
    }
}

public class Reachability {

    func connectionStatus() -> ReachabilityStatus {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)

        guard let defaultRouteReachability = (withUnsafePointer(to: &zeroAddress) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }) else {
           return .Unknown
        }

        var flags : SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return .Unknown
        }

        return ReachabilityStatus(reachabilityFlags: flags)
    }

    func monitorReachabilityChanges() {
        let host = "google.com"
        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
        let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

        SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
            let status = ReachabilityStatus(reachabilityFlags: flags)

            NotificationCenter.default.post(name: NSNotification.Name(rawValue: ReachabilityStatusChangedNotification), object: nil, userInfo: ["Status": status.description])}, &context)

        SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue)
    }
}

extension ReachabilityStatus {

    public init(reachabilityFlags flags: SCNetworkReachabilityFlags) {
        let connectionRequired = flags.contains(.connectionRequired)
        let isReachable = flags.contains(.reachable)
        let isWWAN = flags.contains(.isWWAN)

        if !connectionRequired && isReachable {
            if isWWAN {
                self = .Online(.WWAN)
            } else {
                self = .Online(.WiFi)
            }
        } else {
            self =  .Offline
        }
    }
}

दिसम्बर 3, 2016, आईओएस 10 और स्विफ्ट 3.1 के रूप में अच्छी तरह से काम कर रहा है, धन्यवाद!
joey

नमस्कार, अगर हम Wifi / 3G / Mobile-Data / 4G कनेक्शन को अलग करना चाहते हैं तो हम कैसे पहचान सकते हैं।

6

चूँकि SendSynchronousRequest को पदावनत कर दिया गया है, इसलिए मैंने यह कोशिश की लेकिन प्रतिक्रिया समाप्त होने से पहले 'रिटर्न स्टेटस' कहलाता था।

यह उत्तर हालांकि अच्छी तरह से काम करता है, स्विफ्ट के साथ इंटरनेट कनेक्शन की जांच करें

यहाँ मैं वैसे भी कोशिश की है:

import Foundation

public class Reachability {

    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
        let session = NSURLSession.sharedSession()

        session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
            print("data \(data)")
            print("response \(response)")
            print("error \(error)")

            if let httpResponse = response as? NSHTTPURLResponse {
                print("httpResponse.statusCode \(httpResponse.statusCode)")
                if httpResponse.statusCode == 200 {
                    Status = true
                }
            }

        }).resume()


        return Status
    }
}

मुझे आपका समाधान पसंद और उपयोग हुआ। लेकिन मैंने इस उत्तर के साथ एक संयुक्त जोड़ा: stackoverflow.com/a/34591379 उर्फ। मैं एक semaphore जोड़ा .. तो मैं कार्य समाप्त करने के लिए प्रतीक्षा करें।
Bjqn

6

स्विफ्ट 3: वाईफाई और इंटरनेट कनेक्शन के लिए चेक :

import Foundation
import SystemConfiguration

public class Reachability {
    public func isConnectedToNetwork() -> Bool {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
        zeroAddress.sin_family = sa_family_t(AF_INET)

        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                SCNetworkReachabilityCreateWithAddress(nil, $0)
            }
        }) else {
            return false
        }

        var flags: SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return false
        }

        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)

        return (isReachable && !needsConnection)
    }
}

उपयोग:

if Reachability.isConnectedToNetwork() == true {
    print("Connected to the internet")
    //  Do something
} else {
    print("No internet connection")
    //  Do something
}

2
public func isConnectedToNetwork() {...}class func isConnectedToNetwork{...}आपके उपयोग के मामले के लिए बदला जाना चाहिए ।
keverly

4

आप नीचे दिए गए उत्तर का भी उपयोग कर सकते हैं।

    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" mean Google
        }
        else
        {
            // No "Internet" no Google
        }
    })
   }

धन्यवाद! मुझे NSHTTPURLResponse के रूप में प्रतिक्रिया से एक ऑटो-सही मिला? के रूप में प्रतिक्रिया करने के लिए! NSHTTPURLResponse? स्विफ्ट 1.2 में।
फ्रांसिस जर्विस

1

स्विफ्ट 3: 3 जी और वाई-फाई कनेक्शन की जाँच करें

DispatchQueue.main.async {
        let url = URL(string: "https://www.google.com")!
        let request = URLRequest(url: url)

        let task = URLSession.shared.dataTask(with: request) {data, response, error in

            if error != nil {
                // do something here...
                print("Internet Connection not Available!")
            }
            else if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode == 200 {
                    // do something here...
                    print("Internet Connection OK")
                }
                print("statusCode: \(httpResponse.statusCode)")
            }

        }
        task.resume()
}

यह पसंदीदा तरीका नहीं है। क्या होगा अगर भविष्य के किसी बिंदु पर प्रदान की गई वेब लिंक प्रतिक्रिया देने या बंद होने के लिए रुक जाती है। मैं इसके लिए Apple SystemConfiguration ढांचे का उपयोग करने की सलाह दूंगा। उपरोक्त उत्तर देखें।
अब्दुल यासीन

1

स्विफ्ट 5 के लिए:

import Network
let monitor = NWPathMonitor()

func checkInterwebs() -> Bool {
    var status = false
    monitor.pathUpdateHandler = { path in
        if path.status == .satisfied {
            status = true  // online
        }
    }
    return status
}

1

स्विफ्ट 4

if isInternetAvailable() {
    print("if called Internet Connectivity success \(isInternetAvailable())");
} else {
    print("else called Internet Connectivity success \(isInternetAvailable())");
}

func isInternetAvailable() -> 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.contains(.reachable)
   let needsConnection = flags.contains(.connectionRequired)
   //   print(isReachable && !needsConnection)
   return (isReachable && !needsConnection)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.