java中可达性分析_如何在Swift中处理互联网连接可达性

java中可达性分析

by Neo Ighodaro

由新Ighodaro

如何在Swift中处理互联网连接可达性 (How to handle internet connection reachability in Swift)

More often than not, mobile applications need an active internet connection to function properly. It is normal, however, for the internet connection to be lost. In cases like these, it is up to the developer to come up with ways to make the experience bearable, or in the least, notify the user.

通常,移动应用程序需要活动的Internet连接才能正常运行。 但是,丢失互联网连接是正常的。 在这种情况下,由开发人员来提出使体验可以忍受的方法,或者至少通知用户。

In this article, we are going to see how we can detect internet connection issues in Swift, and some ways we can handle it.

在本文中,我们将了解如何在Swift中检测互联网连接问题,以及一些解决方法。

Here is the sample application we will be building and how it handles different internet connectivity scenarios:

这是我们将要构建的示例应用程序,以及它如何处理不同的Internet连接方案:

要求 (Requirements)

For you to be able to follow along in this article, you will need the following requirements:

为了能够按照本文进行操作,您将需要满足以下要求:

  • Xcode installed on your machine.

    Xcode安装在您的计算机上。

  • Knowledge of the Swift programming language.

    了解Swift编程语言。
  • Cocoapods installed on your machine.

    您的机器上安装了可可足类

When you have the above requirements, let’s dive in.

满足上述要求后,让我们开始吧。

设置我们的工作区 (Setting up our workspace)

Before we begin, we will create a playground. This is where we will write all our use cases and handle them.

在开始之前,我们将创建一个游乐场。 在这里,我们将编写所有用例并进行处理。

Swift comes with its own Reachability implementation for detecting connection issues, but we will be using a third-party library. We are doing this because it is easier and the API is more expressive than the one built in.

Swift带有其自己的Reachability实现,用于检测连接问题,但是我们将使用第三方库 。 我们这样做是因为它比内置的API更容易且API更具表达性。

Open Xcode and set up a new project.

打开Xcode并设置一个新项目。

This project will be a simple playground that we can experiment with.

这个项目将是一个我们可以尝试的简单游乐场。

To detect when the connection goes offline we are going to be using the Reachability.swift ****package. It is a “replacement for Apple’s Reachability re-written in Swift with closures”.

为了检测连接何时脱机,我们将使用Reachability.swift ****软件包。 这是“用Swift在闭包中重写Apple的可到达性”。

Open your terminal and run the command below:

打开终端并运行以下命令:

$ pod init

This will create a new Podfile where we can declare the Cocoapods dependencies. Open the Podfile and replace the contents with the code below:

这将创建一个新的Podfile ,我们可以在其中声明Cocoapods依赖项。 打开Podfile并将内容替换为以下代码:

platform :ios, '9.0'
target 'project_name' do    use_frameworks!    pod 'ReachabilitySwift'    pod 'Alamofire'end

You need to replace **project_name** with the name of your project.

您需要将 **project_name** 替换 为您的项目名称。

Save the file and run the command below to install the Pods to your project:

保存文件并运行以下命令,将Pod安装到您的项目中:

$ pod install

When the installation is complete, open the *.xcworkspace file in the root of your project. This will launch Xcode.

安装完成后,打开项目根目录中的*.xcworkspace文件。 这将启动Xcode。

创建我们的网络可达性管理器 (Creating our Network Reachability Manager)

Create a new NetworkManager class. This class will store the network status and be a simple proxy to the Reachability package. In the file, paste the code below:

创建一个新的NetworkManager类。 此类将存储网络状态,并且是“可到达Reachability包的简单代理。 在文件中,粘贴以下代码:

import Foundationimport Reachability
class NetworkManager: NSObject {
var reachability: Reachability!
static let sharedInstance: NetworkManager = {         return NetworkManager()     }()
override init() {        super.init()
// Initialise reachability        reachability = Reachability()!
// Register an observer for the network status        NotificationCenter.default.addObserver(            self,            selector: #selector(networkStatusChanged(_:)),            name: .reachabilityChanged,            object: reachability        )
do {            // Start the network status notifier            try reachability.startNotifier()        } catch {            print("Unable to start notifier")        }    }
@objc func networkStatusChanged(_ notification: Notification) {        // Do something globally here!    }
static func stopNotifier() -> Void {        do {            // Stop the network status notifier            try (NetworkManager.sharedInstance.reachability).startNotifier()        } catch {            print("Error stopping notifier")        }    }
// Network is reachable    static func isReachable(completed: @escaping (NetworkManager) -> Void) {        if (NetworkManager.sharedInstance.reachability).connection != .none {            completed(NetworkManager.sharedInstance)        }    }
// Network is unreachable    static func isUnreachable(completed: @escaping (NetworkManager) -> Void) {        if (NetworkManager.sharedInstance.reachability).connection == .none {            completed(NetworkManager.sharedInstance)        }    }
// Network is reachable via WWAN/Cellular    static func isReachableViaWWAN(completed: @escaping (NetworkManager) -> Void) {        if (NetworkManager.sharedInstance.reachability).connection == .cellular {            completed(NetworkManager.sharedInstance)        }    }
// Network is reachable via WiFi    static func isReachableViaWiFi(completed: @escaping (NetworkManager) -> Void) {        if (NetworkManager.sharedInstance.reachability).connection == .wifi {            completed(NetworkManager.sharedInstance)        }    }]

In the class above, we have defined a couple of helper functions that will help us get started with network status monitoring. We have a sharedInstance that is a singleton and we can call that if we do not want to create multiple instances of the NetworkManager class.

在上面的类中,我们定义了几个帮助程序功能,这些功能将帮助我们开始进行网络状态监视。 我们有一个sharedInstance ,它是一个单例,如果我们不想创建NetworkManager类的多个实例,可以调用它。

In the init method, we create an instance of Reachability and then we register a notification using the NotificationCenter class. Now, every time the network status changes, the callback specified by NotificationCenter (which is networkStatusChanged) will be called. We can use this to do something global that is activated when the network is unreachable.

init方法中,我们创建一个Reachability实例,然后使用NotificationCenter类注册一个通知。 现在,每次网络状态更改时,将调用NotificationCenter指定的回调(即networkStatusChanged )。 我们可以使用它来执行全局性操作,该操作在网络不可达时被激活。

We have defined other helper functions that will generally make running code, depending on the status of our internet connection, a breeze. We have *isReachable*, *isUnreachable*, *isReachableViaWWAN* and *isReachableViaWiFi*.

我们定义了其他帮助程序函数,这些函数通常使运行代码变得容易,具体取决于我们的Internet连接状态。 我们有*isReachable**isUnreachable**isReachableViaWWAN**isReachableViaWiFi*

The usage of one of these helpers will generally look like this:

这些助手之一的用法通常如下所示:

NetworkManager.isReachable { networkManagerInstance in  print("Network is available")}
NetworkManager.isUnreachable { networkManagerInstance in  print("Network is Unavailable")}

This is not an event listener and will only run once. To use a listener to pick up network changes in real-time, you’ll need to use NetworkManager.sharedInstance.reachability.whenReachable**. We will show an example later in the article.**

这不是事件侦听器,只会运行一次。 要使用侦听器实时获取网络更改,您需要使用 NetworkManager.sharedInstance.reachability.whenReachable **。 我们将在本文后面的示例中显示一个示例。**

Now that we have a manager class, let’s see how we can use this in an application.

现在我们有了一个经理类,让我们看看如何在应用程序中使用它。

在应用程序启动时处理网络可用性 (Handling Network Availability on Application Launch)

Sometimes, your application relies heavily on an internet connection and you need to detect the status on launch. Let’s see how we can handle this using the NetworkManager class.

有时,您的应用程序严重依赖Internet连接,因此您需要在启动时检测状态。 让我们看看如何使用NetworkManager类处理此问题。

Create a new controller called LaunchViewController. We will treat the first controller view on the storyboard as the launch controller. We will try to detect if the user’s device is online and, if not, we will create an offline page to handle this so the user does not get into the application at all.

创建一个名为LaunchViewController的新控制器。 我们将情节提要上的第一个控制器视图视为启动控制器。 我们将尝试检测用户的设备是否在线,否则,我们将创建一个脱机页面来处理此问题,因此用户根本不会进入该应用程序。

In the LaunchController, replace the contents with the following code:

LaunchController ,将内容替换为以下代码:

import UIKit
class LaunchViewController: UIViewController {    let network: NetworkManager = NetworkManager.sharedInstance
override func viewDidLoad() {        super.viewDidLoad()
NetworkManager.isUnreachable { _ in            self.showOfflinePage()        }    }
private func showOfflinePage() -> Void {        DispatchQueue.main.async {            self.performSegue(                withIdentifier: "NetworkUnavailable",                 sender: self            )        }    }}

In this class, we use our NetworkManager‘s *isUnreachable* method to fire the showOffline method when the network is unavailable. Let us create that view controller. Create a new view controller called OfflineViewController.

在此类中,我们使用NetworkManager*isUnreachable*方法在网络不可用时触发showOffline方法。 让我们创建该视图控制器。 创建一个名为OfflineViewController的新视图控制器。

Open the Main.storyboard file and set the custom class of the first view to LaunchViewController .

打开Main.storyboard文件,然后将第一个视图的自定义类设置为LaunchViewController

Next, create a new view controller in the storyboard. Set the OfflineViewController as the custom class for this new view controller. Now create a manual segue called NetworkUnavailable between the new view controller and the LaunchViewController. When you are done you should have something similar to this:

接下来,在情节提要中创建一个新的视图控制器。 将OfflineViewController设置为此新视图控制器的自定义类。 现在,在新的视图控制器和LaunchViewController之间创建一个名为NetworkUnavailable的手动LaunchViewController 。 完成后,您应该具有类似以下内容:

Now let’s run the application. Note, though, that before you run your application, your development machine should be offline as the iOS simulator uses the machine’s internet connection. When you run the application, you should get the offline page we created.

现在让我们运行该应用程序。 但是请注意,在运行应用程序之前,您的开发计算机应处于脱机状态,因为iOS模拟器使用了该计算机的Internet连接。 运行应用程序时,您应该获得我们创建的离线页面。

Now let us create a view controller that shows up when there is a connection.

现在,让我们创建一个视图控制器,该控制器在有连接时显示。

设备上线时处理事件 (Handling Events When the Device Comes Online)

Now that we have created an Offline View Controller and it works when the device is offline, let us handle what happens when the device is back online.

既然我们已经创建了一个离线视图控制器,并且它在设备离线时也可以工作,那么让我们来处理当设备重新在线时发生的情况。

Create a new navigation view controller on the storyboard below the Offline View Controller. We will create a controller that displays the latest Reddit posts. Create a new view controller class called PostsTableViewController. Now make this the custom class for the view controller attached to the Navigation View Controller.

在“离线视图控制器”下方的情节提要中创建一个新的导航视图控制器。 我们将创建一个显示最新Reddit帖子的控制器。 创建一个名为PostsTableViewController的新视图控制器类。 现在,使它成为附加到导航视图控制器的视图控制器的自定义类。

Now create a manual segue called MainController from the Navigation View Controller to the Launch View Controller and the Offline View Controller. You should have something similar to this:

现在,从Navigation View Controller到Launch View Controller和Offline View Controller创建一个称为MainController的手动设置。 您应该有类似以下内容:

Now, open the LaunchViewController class and at the bottom of the viewDidLoad method add the following:

现在,打开LaunchViewController类,并在viewDidLoad方法的底部添加以下内容:

NetworkManager.isReachable { _ in    self.showMainPage()}

Then add the method below to the controller:

然后将以下方法添加到控制器:

private func showMainPage() -> Void {    DispatchQueue.main.async {        self.performSegue(            withIdentifier: "MainController",             sender: self        )    }}

This will make sure that when the app is launched, it will check for connectivity and then, if the connection is available, it will present the PostsTableViewController. Otherwise it will present the OfflineViewController.

这将确保启动应用程序时,它将检查连接性,然后,如果连接可用,它将显示PostsTableViewController 。 否则,它将显示OfflineViewController

Great! But what happens when the user has hit the OfflineViewController and then the network comes back online? Let’s handle that scenario.

大! 但是,当用户点击了OfflineViewController之后网络又恢复了在线状态时,会发生什么? 让我们处理这种情况。

Open the OfflineViewController and replace the code with the code below:

打开OfflineViewController并将代码替换为以下代码:

import UIKit
class OfflineViewController: UIViewController {    let network = NetworkManager.sharedInstance
override func viewDidLoad() {        super.viewDidLoad()
// If the network is reachable show the main controller        network.reachability.whenReachable = { _ in            self.showMainController()        }    }
override func viewWillAppear(_ animated: Bool) {        super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)    }
override func viewWillDisappear(_ animated: Bool) {        super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)    }
private func showMainController() -> Void {        DispatchQueue.main.async {            self.performSegue(withIdentifier: "MainController", sender: self)        }    }}

In the controller above, you can see, in the viewDidLoad method, that we set the whenReachable completion to show the main controller. This means that, as long as its offline, you watch for when the device comes back online. When it does, present the PostsTableViewController.

在上面的控制器中,您可以在viewDidLoad方法中看到我们设置了whenReachable完成以显示主控制器。 这意味着,只要设备离线,您就可以监视设备何时恢复在线。 完成后,显示PostsTableViewController

We also override the viewWillAppear and viewWillDisappear methods to ensure the navigation bar does not show on the Offline View Controller.

我们还将重写viewWillAppearviewWillDisappear方法,以确保导航栏不会显示在Offline View Controller上。

在Swift中从Reddit API获取帖子 (Fetching Posts from Reddit API in Swift)

Now let us add the logic that’ll fetch data from Reddit and display on our PostsTableViewController. Open the file and replace the contents with the code below:

现在,让我们添加将从Reddit获取数据并显示在PostsTableViewController上的PostsTableViewController 。 打开文件,并将内容替换为以下代码:

import UIKitimport Alamofire
struct RedditPost {    let title: String!    let subreddit: String!}
class PostsTableViewController: UITableViewController {    var posts = [RedditPost]()
let network = NetworkManager.sharedInstance
override func viewDidLoad() {        super.viewDidLoad()        navigationItem.title = "Latest Posts"
// Fetch the posts and then reload the table        fetchPosts { posts in            self.posts = posts            self.tableView.reloadData()        }    }
private func fetchPosts(completion: @escaping (_ posts: [RedditPost]) -> Void) -> Void {        // Send a request to the Reddit API        Alamofire.request("https://api.reddit.com").validate().responseJSON { response in            switch response.result {            case .success(let JSON):                let data = JSON as! [String:AnyObject]                guard let children = data["data"]!["children"] as? [AnyObject] else { return }                var posts = [RedditPost]()
// Loop through the Reddit posts and then assign a post to the posts array                for child in 0...children.count-1 {                    let post = children[child]["data"] as! [String: AnyObject]
posts.append(RedditPost(                        title: post["title"] as! String,                        subreddit: "/r/" + (post["subreddit"] as! String)                    ))                }
DispatchQueue.main.async {                    completion(posts)                }            case .failure(let error):                print(error)            }        }    }
override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()    }
// MARK: - Table view data source    override func numberOfSections(in tableView: UITableView) -> Int {        return 1    }
// Return the number of posts available    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return self.posts.count    }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath)        let post = posts[indexPath.row] as RedditPost        cell.textLabel?.text = post.title        cell.detailTextLabel?.text = post.subreddit        return cell    }}

In the fetchPosts method, we use Alamofire to send a GET request to the Reddit API. We then parse the response and add it to the RedditPost struct we created at the top of the file. This makes the data we are passing to the tableView consistent.

fetchPosts方法中,我们使用Alamofire将GET请求发送到Reddit API。 然后,我们解析响应并将其添加到我们在文件顶部创建的RedditPost结构中。 这使我们传递给tableView的数据保持一致。

设备离线时处理事件 (Handling Events when the Device Goes Offline)

Now, let us handle one more scenario. Imagine while viewing the latest Reddit posts, you lose connectivity. What happens? Let’s show the offline page again when that happens.

现在,让我们处理另一种情况。 想象一下,在查看最新的Reddit帖子时,您失去了连接。 怎么了? 发生这种情况时,让我们再次显示离线页面。

As was previously done, create a manual segue called NetworkUnavailable from the PostsTableViewController to the OfflineViewController. Now add this code to the bottom of the viewDidLoad method:

和以前一样,从PostsTableViewControllerOfflineViewController创建一个名为NetworkUnavailable的手动OfflineViewController 。 现在,将此代码添加到viewDidLoad方法的底部:

network.reachability.whenUnreachable = { reachability in    self.showOfflinePage()}

Now add the method below to the controller:

现在将以下方法添加到控制器:

private func showOfflinePage() -> Void {    DispatchQueue.main.async {        self.performSegue(withIdentifier: "NetworkUnavailable", sender: self)    }}

This will listen for when the device goes offline and, if that happens, it will showOfflinePage.

这将侦听设备何时离线,如果发生离线,它将显示showOfflinePage

That’s all! We have been able to handle offline and online events using our NetworkManager in Swift.

就这样! 我们已经能够使用Swift中的NetworkManager处理离线和在线事件。

结论 (Conclusion)

In this article, we considered how to make sure your application can handle online and offline events when they happen. You can always implement this any way you wish. If you have any questions or feedback, leave them below in the comments.

在本文中,我们考虑了如何确保您的应用程序可以在事件发生时处理联机和脱机事件。 您始终可以按照自己的意愿实施此操作。 如果您有任何问题或反馈,请将其留在评论中。

The source code to this playground is available on GitHub.

该游乐场的源代码可在GitHub找到

This article was first published on Pusher.

本文最初在Pusher上发表。

翻译自: https://www.freecodecamp.org/news/how-to-handle-internet-connection-reachability-in-swift-34482301ea57/

java中可达性分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值