Computer >> 컴퓨터 >  >> 네트워킹 >> 인터넷

Swift에서 인터넷 연결 감지 및 관리:실용 가이드

네오 이고다로

대개 모바일 애플리케이션이 제대로 작동하려면 활성 인터넷 연결이 필요합니다. 그러나 인터넷 연결이 끊어지는 것은 정상입니다. 이러한 경우, 견딜 수 있는 경험을 제공하는 방법을 강구하거나 최소한 사용자에게 알리는 것은 개발자의 몫입니다.

이 글에서는 Swift에서 인터넷 연결 문제를 감지하는 방법과 이를 처리할 수 있는 몇 가지 방법을 살펴보겠습니다.

다음은 우리가 구축할 샘플 애플리케이션과 다양한 인터넷 연결 시나리오를 처리하는 방법입니다.

Swift에서 인터넷 연결 감지 및 관리:실용 가이드

요구사항

이 문서를 따라가려면 다음 요구 사항이 필요합니다:

  • 컴퓨터에 Xcode가 설치되어 있습니다.
  • Swift 프로그래밍 언어에 대한 지식
  • 컴퓨터에 Cocoapod가 설치되어 있습니다.

위의 요구 사항이 충족되면 자세히 살펴보겠습니다.

작업 공간 설정

시작하기 전에 놀이터를 만들어 보겠습니다. 여기에서 모든 사용 사례를 작성하고 처리하게 됩니다.

Swift에는 연결 문제를 감지하기 위한 자체 Reachability 구현이 포함되어 있지만 우리는 타사 라이브러리를 사용할 것입니다. 우리가 이렇게 하는 이유는 내장된 것보다 API가 더 쉽고 표현력이 더 풍부하기 때문입니다.

Xcode를 열고 새 프로젝트를 설정하세요.

Swift에서 인터넷 연결 감지 및 관리:실용 가이드

이 프로젝트는 우리가 실험할 수 있는 간단한 놀이터가 될 것입니다.

연결이 오프라인이 되는 시점을 감지하기 위해 Reachability.swift를 사용할 것입니다. ** 패키지. 이는 "Swift에서 클로저로 다시 작성된 Apple의 접근성을 대체하는 것"입니다.

터미널을 열고 아래 명령을 실행하세요:

$ pod init

그러면 새로운 Podfile가 생성됩니다. 여기서 Cocoapods 종속성을 선언할 수 있습니다. Podfile 열기 내용을 아래 코드로 바꾸세요:

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

교체해야 합니다 **project_name** 프로젝트 이름

파일을 저장하고 아래 명령을 실행하여 프로젝트에 Pod를 설치하세요.

$ pod install

설치가 완료되면 *.xcworkspace을 엽니다. 프로젝트 루트에 있는 파일입니다. 그러면 Xcode가 실행됩니다.

Network Reachability Manager 생성

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

위 클래스에서는 네트워크 상태 모니터링을 시작하는 데 도움이 되는 몇 가지 도우미 함수를 정의했습니다. sharedInstance가 있습니다 이는 싱글톤이고 NetworkManager의 여러 인스턴스를 생성하지 않으려면 이를 호출할 수 있습니다. 수업.

init에서 메소드를 사용하여 Reachability의 인스턴스를 생성합니다. 그런 다음 NotificationCenter를 사용하여 알림을 등록합니다. 수업. 이제 네트워크 상태가 변경될 때마다 NotificationCenter에 의해 지정된 콜백이 (networkStatusChanged입니다. )이 호출됩니다. 이를 사용하여 네트워크에 연결할 수 없을 때 활성화되는 전역 작업을 수행할 수 있습니다.

우리는 일반적으로 인터넷 연결 상태에 따라 코드 실행을 쉽게 만드는 다른 도우미 함수를 정의했습니다. *isReachable*이 있습니다. , *isUnreachable* , *isReachableViaWWAN**isReachableViaWiFi* .

이러한 도우미 중 하나의 사용법은 일반적으로 다음과 같습니다:

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

이것은 이벤트 리스너가 아니며 한 번만 실행됩니다. 리스너를 사용하여 네트워크 변경 사항을 실시간으로 확인하려면 다음을 사용해야 합니다. NetworkManager.sharedInstance.reachability.whenReachable <강한>. 기사 뒷부분에서 예시를 보여드리겠습니다.

이제 관리자 클래스가 있으므로 이를 애플리케이션에서 어떻게 사용할 수 있는지 살펴보겠습니다.

애플리케이션 실행 시 네트워크 가용성 처리

때로는 애플리케이션이 인터넷 연결에 크게 의존하므로 실행 시 상태를 감지해야 하는 경우가 있습니다. NetworkManager를 사용하여 이를 어떻게 처리할 수 있는지 살펴보겠습니다. 수업.

LaunchViewController라는 새 컨트롤러를 만듭니다. . 스토리보드의 첫 번째 컨트롤러 보기를 실행 컨트롤러로 처리하겠습니다. 우리는 사용자의 기기가 온라인인지 감지하고, 그렇지 않은 경우 이를 처리하기 위해 오프라인 페이지를 만들어 사용자가 애플리케이션에 전혀 접속하지 못하도록 할 것입니다.

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

이 수업에서는 NetworkManager를 사용합니다. *isUnreachable* showOffline를 실행하는 메서드 네트워크를 사용할 수 없을 때의 방법입니다. 해당 뷰 컨트롤러를 만들어 보겠습니다. OfflineViewController라는 새 뷰 컨트롤러를 만듭니다. .

Main.storyboard 열기 파일을 만들고 첫 번째 보기의 사용자 정의 클래스를 LaunchViewController로 설정합니다. .

다음으로 스토리보드에 새 뷰 컨트롤러를 만듭니다. OfflineViewController을 설정하세요 이 새로운 뷰 컨트롤러의 사용자 정의 클래스로. 이제 NetworkUnavailable라는 수동 segue를 만듭니다. 새 뷰 컨트롤러와 LaunchViewController 사이 . 완료되면 다음과 유사한 내용이 표시됩니다:

Swift에서 인터넷 연결 감지 및 관리:실용 가이드

이제 애플리케이션을 실행해 보겠습니다. 하지만 iOS 시뮬레이터는 머신의 인터넷 연결을 사용하므로 애플리케이션을 실행하기 전에 개발 머신이 오프라인 상태여야 합니다. 애플리케이션을 실행하면 우리가 만든 오프라인 페이지가 나타납니다.

이제 연결이 있을 때 표시되는 뷰 컨트롤러를 만들어 보겠습니다.

기기가 온라인 상태가 될 때 이벤트 처리

이제 Offline View Controller를 만들었고 장치가 오프라인일 때 작동하므로 장치가 다시 온라인이 되었을 때 어떤 일이 발생하는지 처리해 보겠습니다.

오프라인 뷰 컨트롤러 아래 스토리보드에 새 탐색 뷰 컨트롤러를 만듭니다. 최신 Reddit 게시물을 표시하는 컨트롤러를 만들겠습니다. PostsTableViewController라는 새 뷰 컨트롤러 클래스를 만듭니다. . 이제 이것을 Navigation View Controller에 연결된 뷰 컨트롤러에 대한 사용자 정의 클래스로 만듭니다.

이제 MainController라는 수동 segue를 만듭니다. Navigation View Controller에서 Launch View Controller 및 Offline View Controller까지. 다음과 비슷한 것이 있어야 합니다:

Swift에서 인터넷 연결 감지 및 관리:실용 가이드

이제 LaunchViewController를 열어보세요. 클래스와 viewDidLoad 하단에 있습니다. 메소드에 다음을 추가하세요:

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

그런 다음 컨트롤러에 아래 메서드를 추가하세요.

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

이렇게 하면 앱이 시작될 때 연결을 확인한 다음 연결이 가능하면 PostsTableViewController가 표시됩니다. . 그렇지 않으면 OfflineViewController가 표시됩니다. .

좋아요! 하지만 사용자가 OfflineViewController을 누르면 어떻게 될까요? 그러면 네트워크가 다시 온라인 상태로 돌아오나요? 그 시나리오를 처리해 보겠습니다.

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

위 컨트롤러에서 viewDidLoad를 볼 수 있습니다. 메서드를 사용하여 whenReachable을 설정했습니다. 완료되면 메인 컨트롤러가 표시됩니다. 이는 오프라인인 동안 장치가 다시 온라인 상태가 될 때를 지켜본다는 것을 의미합니다. 그렇다면 PostsTableViewController를 제시하세요. .

viewWillAppear도 재정의합니다. 및 viewWillDisappear Offline View Controller에 탐색 표시줄이 표시되지 않도록 하는 방법입니다.

Swift의 Reddit API에서 게시물 가져오기

이제 Reddit에서 데이터를 가져와 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 }}

fetchPosts에서 메서드에서는 Alamofire을 사용합니다. Reddit API에 GET 요청을 보냅니다. 그런 다음 응답을 구문 분석하여 RedditPost에 추가합니다. 파일 상단에 생성한 구조체입니다. 이렇게 하면 우리가 tableView에 전달하는 데이터가 일관성이 있습니다.

기기가 오프라인일 때 이벤트 처리

이제 시나리오를 하나 더 처리해 보겠습니다. 최신 Reddit 게시물을 보는 동안 연결이 끊어진다고 상상해 보세요. 무슨 일이 일어나나요? 그럴 때는 오프라인 페이지를 다시 보여주자.

이전과 마찬가지로 NetworkUnavailable라는 수동 segue를 만듭니다. PostsTableViewController에서 OfflineViewController로 . 이제 이 코드를 viewDidLoad 하단에 추가하세요. 방법:

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

이제 아래 메소드를 컨트롤러에 추가하세요:

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

이는 기기가 오프라인이 될 때를 수신 대기하며, 오프라인이 발생하면 showOfflinePage됩니다. .

그게 다야! Swift의 NetworkManager를 사용하여 오프라인 및 온라인 이벤트를 처리할 수 있었습니다.

결론

이 기사에서는 온라인 및 오프라인 이벤트가 발생할 때 애플리케이션이 이를 처리할 수 있는지 확인하는 방법을 고려했습니다. 언제든지 원하는 방식으로 이를 구현할 수 있습니다. 질문이나 의견이 있으시면 아래 댓글에 남겨주세요.

이 플레이그라운드의 소스 코드는 GitHub에서 확인할 수 있습니다.

이 기사는 푸셔(Pusher)에 처음 게재되었습니다.

무료로 코딩을 배우세요. freeCodeCamp의 오픈 소스 커리큘럼은 40,000명 이상의 사람들이 개발자로 취업하는 데 도움을 주었습니다. 시작하세요