Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบเครือข่าย >> อินเทอร์เน็ต

การตรวจจับและจัดการการเชื่อมต่ออินเทอร์เน็ตใน Swift:คู่มือปฏิบัติ

โดย นีโอ อิโกดาโร

บ่อยครั้ง แอปพลิเคชันมือถือจำเป็นต้องมีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานได้เพื่อให้ทำงานได้อย่างถูกต้อง อย่างไรก็ตาม เป็นเรื่องปกติที่การเชื่อมต่ออินเทอร์เน็ตจะขาดหาย ในกรณีเช่นนี้ ขึ้นอยู่กับนักพัฒนาซอฟต์แวร์ที่จะต้องหาวิธีที่จะทำให้ประสบการณ์นี้น่าจดจำ หรืออย่างน้อยที่สุดก็แจ้งให้ผู้ใช้ทราบ

ในบทความนี้ เราจะมาดูกันว่าเราจะตรวจพบปัญหาการเชื่อมต่ออินเทอร์เน็ตใน Swift ได้อย่างไร และวิธีจัดการกับปัญหาบางอย่าง

นี่คือแอปพลิเคชันตัวอย่างที่เราจะสร้างและวิธีจัดการกับสถานการณ์การเชื่อมต่ออินเทอร์เน็ตที่แตกต่างกัน:

การตรวจจับและจัดการการเชื่อมต่ออินเทอร์เน็ตใน Swift:คู่มือปฏิบัติ

ข้อกำหนด

เพื่อให้คุณสามารถปฏิบัติตามบทความนี้ได้ คุณจะต้องมีข้อกำหนดต่อไปนี้:

  • ติดตั้ง Xcode บนเครื่องของคุณแล้ว
  • ความรู้เกี่ยวกับภาษาการเขียนโปรแกรม Swift
  • Cocoapods ติดตั้งอยู่บนเครื่องของคุณ

เมื่อคุณมีข้อกำหนดข้างต้นแล้ว มาเริ่มกันเลย

การตั้งค่าพื้นที่ทำงานของเรา

ก่อนที่เราจะเริ่ม เราจะสร้างสนามเด็กเล่น ที่นี่เราจะเขียนกรณีการใช้งานทั้งหมดของเราและจัดการกับกรณีเหล่านั้น

Swift มาพร้อมกับการใช้งาน Reachability ของตัวเองเพื่อตรวจจับปัญหาการเชื่อมต่อ แต่เราจะใช้ไลบรารีของบุคคลที่สาม เรากำลังทำเช่นนี้เพราะมันง่ายกว่าและ API แสดงออกได้มากกว่าในตัว

เปิด Xcode และตั้งค่าโปรเจ็กต์ใหม่

การตรวจจับและจัดการการเชื่อมต่ออินเทอร์เน็ตใน Swift:คู่มือปฏิบัติ

โปรเจ็กต์นี้จะเป็นสนามเด็กเล่นง่ายๆ ที่เราสามารถทดลองได้

เพื่อตรวจจับเมื่อการเชื่อมต่อออฟไลน์ เราจะใช้ Reachability.swift ** แพคเกจ มันคือ "การแทนที่ความสามารถในการเข้าถึงของ Apple ที่เขียนใหม่ด้วย Swift พร้อมการปิด"

เปิดเทอร์มินัลของคุณและรันคำสั่งด้านล่าง:

$ pod init

สิ่งนี้จะสร้าง 05 ใหม่ โดยที่เราสามารถประกาศการพึ่งพาของ Cocoapods ได้ เปิด 10 และแทนที่เนื้อหาด้วยโค้ดด้านล่าง:

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

คุณต้องเปลี่ยน 23 พร้อมชื่อโครงการของคุณ

บันทึกไฟล์และรันคำสั่งด้านล่างเพื่อติดตั้ง Pods ให้กับโปรเจ็กต์ของคุณ:

$ pod install

เมื่อการติดตั้งเสร็จสมบูรณ์ ให้เปิด 33 ไฟล์ในรูทของโปรเจ็กต์ของคุณ นี่จะเป็นการเปิด Xcode

การสร้าง Network Reachability Manager ของเรา

สร้าง 46 ใหม่ ชั้นเรียน คลาสนี้จะจัดเก็บสถานะเครือข่ายและเป็นพร็อกซีอย่างง่ายไปยัง 56 แพคเกจ ในไฟล์ ให้วางโค้ดด้านล่าง:

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

ในชั้นเรียนข้างต้น เราได้กำหนดฟังก์ชันตัวช่วยสองสามฟังก์ชันที่จะช่วยให้เราเริ่มต้นการตรวจสอบสถานะเครือข่ายได้ เรามี 67 นั่นคือซิงเกิลตันและเราสามารถเรียกสิ่งนั้นได้หากเราไม่ต้องการสร้างหลายอินสแตนซ์ของ 75 ชั้นเรียน

ใน 80 วิธีการเราสร้างอินสแตนซ์ของ 93 จากนั้นเราจะลงทะเบียนการแจ้งเตือนโดยใช้ 102 ชั้นเรียน ตอนนี้ทุกครั้งที่สถานะเครือข่ายเปลี่ยนแปลง การโทรกลับจะระบุด้วย 119 (ซึ่งก็คือ 125 ) จะถูกเรียก เราสามารถใช้สิ่งนี้เพื่อทำบางสิ่งระดับโลกที่จะเปิดใช้งานเมื่อเครือข่ายไม่สามารถเข้าถึงได้

เราได้กำหนดฟังก์ชันตัวช่วยอื่นๆ ซึ่งโดยทั่วไปแล้วจะทำให้โค้ดที่รันอยู่นั้นเป็นเรื่องง่าย โดยขึ้นอยู่กับสถานะการเชื่อมต่ออินเทอร์เน็ตของเรา เรามี 136 , 140 , 155 และ 166 .

โดยทั่วไปการใช้งานตัวช่วยเหล่านี้จะมีลักษณะดังนี้:

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

นี่ไม่ใช่ Listener กิจกรรมและจะทำงานเพียงครั้งเดียวเท่านั้น หากต้องการใช้ Listener เพื่อรับการเปลี่ยนแปลงเครือข่ายแบบเรียลไทม์ คุณจะต้องใช้ 179 <แข็งแกร่ง> เราจะแสดงตัวอย่างในบทความต่อไป

ตอนนี้เรามีคลาสผู้จัดการแล้ว มาดูกันว่าเราจะใช้คลาสนี้ในแอปพลิเคชันได้อย่างไร

การจัดการความพร้อมใช้งานของเครือข่ายเมื่อเปิดแอปพลิเคชัน

บางครั้งแอปพลิเคชันของคุณอาศัยการเชื่อมต่ออินเทอร์เน็ตเป็นอย่างมาก และคุณจำเป็นต้องตรวจสอบสถานะเมื่อเปิดใช้งาน มาดูกันว่าเราจะจัดการเรื่องนี้โดยใช้ 181 ได้อย่างไร ชั้นเรียน

สร้างคอนโทรลเลอร์ใหม่ชื่อ 195 . เราจะถือว่ามุมมองคอนโทรลเลอร์แรกบนกระดานเรื่องราวเป็นตัวควบคุมการเปิดตัว เราจะพยายามตรวจสอบว่าอุปกรณ์ของผู้ใช้ออนไลน์อยู่หรือไม่ และหากไม่ เราจะสร้างเพจออฟไลน์เพื่อจัดการสิ่งนี้ เพื่อไม่ให้ผู้ใช้เข้าสู่แอปพลิเคชันเลย

ใน 207 ให้แทนที่เนื้อหาด้วยโค้ดต่อไปนี้:

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

ในคลาสนี้ เราใช้ 215 222 ของ วิธีการยิง 237 วิธีการเมื่อเครือข่ายไม่พร้อมใช้งาน ให้เราสร้างตัวควบคุมมุมมองนั้น สร้างตัวควบคุมมุมมองใหม่ชื่อ 242 .

เปิด 251 ไฟล์และตั้งค่าคลาสที่กำหนดเองของมุมมองแรกเป็น 267 .

จากนั้น สร้างตัวควบคุมมุมมองใหม่ในกระดานเรื่องราว ตั้งค่า 273 เป็นคลาสที่กำหนดเองสำหรับตัวควบคุมมุมมองใหม่นี้ ตอนนี้สร้างการทำต่อแบบแมนนวลชื่อ 287 ระหว่างตัวควบคุมมุมมองใหม่และ 294 . เมื่อคุณทำเสร็จแล้ว คุณควรจะมีสิ่งที่คล้ายกับสิ่งนี้:

การตรวจจับและจัดการการเชื่อมต่ออินเทอร์เน็ตใน Swift:คู่มือปฏิบัติ

ตอนนี้เรามาเรียกใช้แอปพลิเคชันกัน อย่างไรก็ตาม โปรดทราบว่าก่อนที่คุณจะเรียกใช้แอปพลิเคชัน เครื่องพัฒนาของคุณควรออฟไลน์เนื่องจากโปรแกรมจำลอง iOS ใช้การเชื่อมต่ออินเทอร์เน็ตของเครื่อง เมื่อคุณเรียกใช้แอปพลิเคชัน คุณควรได้รับเพจออฟไลน์ที่เราสร้างขึ้น

ตอนนี้ให้เราสร้างตัวควบคุมมุมมองที่จะปรากฏขึ้นเมื่อมีการเชื่อมต่อ

การจัดการเหตุการณ์เมื่ออุปกรณ์ออนไลน์

ตอนนี้เราได้สร้างตัวควบคุมมุมมองออฟไลน์และทำงานได้เมื่ออุปกรณ์ออฟไลน์ ให้เราจัดการกับสิ่งที่จะเกิดขึ้นเมื่ออุปกรณ์กลับมาออนไลน์อีกครั้ง

สร้างตัวควบคุมมุมมองการนำทางใหม่บนกระดานเรื่องราวด้านล่างตัวควบคุมมุมมองออฟไลน์ เราจะสร้างตัวควบคุมที่แสดงโพสต์ Reddit ล่าสุด สร้างคลาสตัวควบคุมมุมมองใหม่ที่เรียกว่า 305 . ตอนนี้ทำให้คลาสนี้เป็นคลาสที่กำหนดเองสำหรับตัวควบคุมมุมมองที่แนบมากับตัวควบคุมมุมมองการนำทาง

ตอนนี้สร้างการทำต่อแบบแมนนวลชื่อ 310 จากตัวควบคุมมุมมองการนำทางไปจนถึงตัวควบคุมมุมมองการเปิดตัวและตัวควบคุมมุมมองออฟไลน์ คุณควรมีสิ่งที่คล้ายกันนี้:

การตรวจจับและจัดการการเชื่อมต่ออินเทอร์เน็ตใน Swift:คู่มือปฏิบัติ

ตอนนี้ เปิด 325 คลาสและที่ด้านล่างของ 337 วิธีการเพิ่มดังต่อไปนี้:

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

จากนั้นเพิ่มวิธีการด้านล่างลงในคอนโทรลเลอร์:

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

เพื่อให้แน่ใจว่าเมื่อเปิดแอปขึ้นมา แอปจะตรวจสอบการเชื่อมต่อ จากนั้นหากการเชื่อมต่อพร้อมใช้งาน แอปจะแสดง 346 . มิฉะนั้นจะแสดง 359 .

เยี่ยมมาก! แต่จะเกิดอะไรขึ้นเมื่อผู้ใช้กด 369 แล้วเครือข่ายก็กลับมาออนไลน์อีกครั้ง? มาจัดการกับสถานการณ์นั้นกันดีกว่า

เปิด 373 และแทนที่โค้ดด้วยโค้ดด้านล่าง:

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

ในตัวควบคุมด้านบน คุณสามารถดูได้ใน 387 วิธีการที่เราตั้งค่า 392 เสร็จสิ้นเพื่อแสดงตัวควบคุมหลัก ซึ่งหมายความว่าตราบใดที่อุปกรณ์ออฟไลน์ คุณจะคอยดูว่าอุปกรณ์กลับมาออนไลน์อีกครั้งเมื่อใด เมื่อเป็นเช่นนั้น ให้แสดง 400 .

เรายังแทนที่ 410 ด้วย และ 422 วิธีการเพื่อให้แน่ใจว่าแถบนำทางไม่แสดงบนตัวควบคุมมุมมองออฟไลน์

กำลังดึงโพสต์จาก Reddit API ใน Swift

ตอนนี้ให้เราเพิ่มตรรกะที่จะดึงข้อมูลจาก Reddit และแสดงบน 435 ของเรา . เปิดไฟล์และแทนที่เนื้อหาด้วยโค้ดด้านล่าง:

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

ใน 448 วิธีการเราใช้ 452 เพื่อส่งคำขอ GET ไปยัง Reddit API จากนั้นเราจะแยกวิเคราะห์การตอบสนองและเพิ่มลงใน 460 struct ที่เราสร้างขึ้นที่ด้านบนของไฟล์ ทำให้ข้อมูลที่เรากำลังส่งไปยัง 472 สม่ำเสมอ

การจัดการเหตุการณ์เมื่ออุปกรณ์ออฟไลน์

ตอนนี้ ให้เราจัดการอีกสถานการณ์หนึ่ง ลองนึกภาพในขณะที่ดูโพสต์ Reddit ล่าสุด คุณจะสูญเสียการเชื่อมต่อ เกิดอะไรขึ้น? มาแสดงหน้าออฟไลน์อีกครั้งเมื่อเกิดเหตุการณ์เช่นนี้

เหมือนที่เคยทำก่อนหน้านี้ ให้สร้างการทำต่อแบบแมนนวลชื่อ 486 จาก 495 ไปที่ 501 . ตอนนี้เพิ่มรหัสนี้ที่ด้านล่างของ 511 วิธีการ:

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

ตอนนี้เพิ่มวิธีการด้านล่างให้กับคอนโทรลเลอร์:

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

การดำเนินการนี้จะคอยฟังเมื่ออุปกรณ์ออฟไลน์ และหากเกิดเหตุการณ์ดังกล่าว อุปกรณ์จะ 527 .

นั่นคือทั้งหมด! เราสามารถจัดการกิจกรรมออฟไลน์และออนไลน์ได้โดยใช้ NetworkManager ใน Swift

บทสรุป

ในบทความนี้ เราได้พิจารณาวิธีการตรวจสอบให้แน่ใจว่าแอปพลิเคชันของคุณสามารถจัดการกับกิจกรรมออนไลน์และออฟไลน์ได้เมื่อเกิดขึ้น คุณสามารถใช้สิ่งนี้ได้ทุกเมื่อตามที่คุณต้องการ หากคุณมีคำถามหรือข้อเสนอแนะ โปรดทิ้งไว้ด้านล่างในความคิดเห็น

ซอร์สโค้ดของ Playground นี้มีอยู่ใน GitHub

บทความนี้เผยแพร่ครั้งแรกบน Pusher

เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น