GitHub - rwbutler/Connectivity: Makes Internet connectivity detection more robus...
source link: https://github.com/rwbutler/Connectivity
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
Connectivity is a wrapper for Apple's Reachability providing a reliable measure of whether Internet connectivity is available where Reachability alone can only indicate whether an interface is available that might allow a connection.
Connectivity's objective is to solve the captive portal problem whereby an iOS device is connected to a WiFi network lacking Internet connectivity. Such situations are commonplace and may occur for example when connecting to a public WiFi network which requires the user to register before use. Connectivity can detect such situations enabling you to react accordingly.
To learn more about how to use Connectivity, take a look at the keynote presentation, check out the blog post, or make use of the table of contents below:
- Features
- What's New in Connectivity 2.0.0?
- Installation
- How It Works
- Usage
- Author
- License
- Additional Software
Features
- Detect captive portals when a device joins a network.
- Detect when connected to a router that has no Internet access.
- Be notified of changes in Internet connectivity.
- Polling connectivity checks may be performed where a constant network connection is required (optional).
What's new in Connectivity 2.0.0?
Connectivity 2.0.0 provides the option of using the new Network
framework on iOS 12 and above. To make use of this functionality set the framework
property to .network
as follows:
let connectivity = Connectivity() connectivity.framework = .network
Below iOS 12, Connectivity will default to the traditional behaviour of using Reachability
to determine the availability of network interfaces.
For more information, refer to CHANGELOG.md.
Installation
Ensure that you include Apple's Reachability header and implementation files (Reachability.h and Reachability.m) to use.
Use of Apple's Reachability is subject to licensing from Apple.
Cocoapods
CocoaPods is a dependency manager which integrates dependencies into your Xcode workspace. To install it using Ruby gems run:
gem install cocoapods
To install Connectivity using Cocoapods, simply add the following line to your Podfile:
pod "Connectivity"
Then run the command:
pod install
For more information see here.
Carthage
Carthage is a dependency manager which produces a binary for manual integration into your project. It can be installed via Homebrew using the commands:
brew update brew install carthage
In order to integrate Connectivity into your project via Carthage, add the following line to your project's Cartfile:
github "rwbutler/Connectivity"
From the macOS Terminal run carthage update --platform iOS
to build the framework then drag Connectivity.framework
into your Xcode project.
For more information see here.
How It Works
iOS adopts a protocol called Wireless Internet Service Provider roaming (WISPr 2.0) published by the Wireless Broadband Alliance. This protocol defines the Smart Client to Access Gateway interface describing how to authenticate users accessing public IEEE 802.11 (Wi-Fi) networks using the Universal Access Method in which a captive portal presents a login page to the user.
The user must then register or provide login credentials via a web browser in order to be granted access to the network using RADIUS or another protocol providing centralized Authentication, Authorization, and Accounting (AAA).
In order to detect a that it has connected to a Wi-Fi network with a captive portal, iOS contacts a number of endpoints hosted by Apple - an example being https://www.apple.com/library/test/success.html. Each endpoint hosts a small HTML page of the form:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <TITLE>Success</TITLE> </HEAD> <BODY> Success </BODY> </HTML>
If on downloading this small HTML page iOS finds that it contains the word Success
as above then it knows that Internet connectivity is available. However, if a login page is presented by a captive portal then the word Success
will not be present and iOS will realize that the network connection has been hijacked by a captive portal and will present a browser window allowing the user to login or register.
Apple hosts a number of these pages such that should one of these pages go down, a number of fallbacks can be checked to determine whether connectivity is present or whether our connection is blocked by the presence of a captive portal. Unfortunately iOS exposes no framework to developers which allows us to make use of the operating system’s awareness of captive portals.
Connectivity is an open-source framework which wraps Reachability and endeavours to replicate iOS’s means of detecting captive portals. When Reachability detects Wi-Fi or WWAN connectivity, Connectivity contacts a number of endpoints to determine whether true Internet connectivity is present or whether a captive portal is intercepting the connections. This approach can also be used to determine whether an iOS device is connected to a Wi-Fi router with no Internet access.
Connectivity provides an interface as close to Reachability as possible so that it is familiar to developers used to working with Reachability. This includes providing the methods startNotifier()
and stopNotifier()
to begin checking for changes in Internet connectivity. Once the notifier has been started, you may query for the current connectivity status synchronously using the status
property (similar to Reachability’s currentReachabilityStatus
) or asynchronously by registering as an observer with the default NotificationCenter for the notification kNetworkConnectivityChangedNotification
(in Swift this is accessed through Notification.Name.ConnectivityDidChange
) — similar to Reachability’s notification kNetworkReachabilityChangedNotification
.
By default, Connectivity contacts a number of endpoints already used by iOS but it recommended that these are supplemented by endpoints hosted by the developer by appending to the connectivityURLs
property. Further customization is possible through setting the successThreshold
property which determines the percentage of endpoints contacted which must result in a successful check in order to conclude that connectivity is present. The default value specifies that 75% of URLs contacted must result in a successful connectivity check.
Usage
For an example of how to use Connectivity, see the sample app in the Example directory.
Callbacks
To get started using Connectivity, simply instantiate an instance and assign a closure to be invoked when Connectivity detects that you are connected to the Internet, when disconnected, or in both cases as follows:
let connectivity: Connectivity = Connectivity() let connectivityChanged: (Connectivity) -> Void = { [weak self] connectivity in self?.updateConnectionStatus(connectivity.status) } connectivity.whenConnected = connectivityChanged connectivity.whenDisconnected = connectivityChanged func updateConnectionStatus(_ status: Connectivity.ConnectivityStatus) { switch status { case .connected: case .connectedViaWiFi: case .connectedViaWiFiWithoutInternet: case .connectedViaWWAN: case .connectedViaWWANWithoutInternet: case .notConnected: } }
Then to start listening for changes in Connectivity call:
connectivity.startNotifier()
Then remember to call connectivity.stopNotifier()
when you are done.
One-Off Checks
Sometimes you only want to check the connectivity state as a one-off. To do so, instantiate a Connectivity object then check the status property as follows:
let connectivity = Connectivity() connectivity.checkConnectivity { connectivity in switch connectivity.status { case .connected: break case .connectedViaWiFi: break case .connectedViaWiFiWithoutInternet: break case .connectedViaWWAN: break case .connectedViaWWANWithoutInternet: break case .notConnected: break } }
Alternatively, you may check the following properties of the Connectivity
object directly if you are only interested in certain types of connections:
var isConnectedViaCellular: Bool var isConnectedViaWiFi: Bool var isConnectedViaCellularWithoutInternet: Bool var isConnectedViaWiFiWithoutInternet: Bool
Connectivity URLs
It is possible to set the URLs which will be contacted to check connectivity via the connectivityURLs
property of the Connectivity
object before starting connectivity checks with startNotifier()
.
connectivity.connectivityURLs = [URL(string: "https://www.apple.com/library/test/success.html")!]
Notifications
If you prefer using notifications to observe changes in connectivity, you may add an observer on the default NotificationCenter:
NotificationCenter.default.addObserver(_:selector:name:object:)
Listening for Notification.Name.ConnectivityDidChange
, the object
property of received notifications will contain the Connectivity
object which you can use to query connectivity status.
Polling
In certain cases you may need to be kept constantly apprised of changes in connectivity state and therefore may wish to enable polling. Where enabled, Connectivity will not wait on changes in Reachability state but will poll the connectivity URLs every 10 seconds (this value is configurable). ConnectivityDidChange
notifications and the closures assigned to the whenConnected
and whenDisconnected
properties will be invoked only where changes in connectivity state occur.
To enable polling:
connectivity.isPollingEnabled = true connectivity.startNotifier()
As always, remember to call stopNotifier()
when you are done.
SSL
As of Connectivity 1.1.0, using HTTPS for connectivity URLs is the default setting. If your app doesn't make use of App Transport Security and you wish to make use of HTTP URLs as well as HTTPS ones then either set isHTTPSOnly
to false
or set shouldUseHTTPS
to false
when instantiating the Connectivity object as follows*:
let connectivity = Connectivity(shouldUseHTTPS: false)
*Note that the property will not be set if you have not set the NSAllowsArbitraryLoads
flag in your app's Info.plist first.
Threshold
To set the number of successful connections required in order to be deemed successfully connected, set the successThreshold
property. The value is specified as a percentage indicating the percentage of successful connections i.e. if four connectivity URLs are set in the connectivityURLs
property and a threshold of 75% is specified then three out of the four checks must succeed in order for our app to be deemed connected:
connectivity.successThreshold = Connectivity.Percentage(75.0)
Author
License
Connectivity is available under the MIT license. See the LICENSE file for more info.
Additional Software
Frameworks
- Connectivity - Improves on Reachability for determining Internet connectivity in your iOS application.
- FeatureFlags - Allows developers to configure feature flags, run multiple A/B or MVT tests using a bundled / remotely-hosted JSON configuration file.
- Skylark - Fully Swift BDD testing framework for writing Cucumber scenarios using Gherkin syntax.
- TailorSwift - A collection of useful Swift Core Library / Foundation framework extensions.
- TypographyKit - Consistent & accessible visual styling on iOS with Dynamic Type support.
Tools
- Config Validator - Config Validator validates & uploads your configuration files and cache clears your CDN as part of your CI process.
- IPA Uploader - Uploads your apps to TestFlight & App Store.
- Palette - Makes your TypographyKit color palette available in Xcode Interface Builder.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK