লেখক: নিও ইঘোদারো
অনেকসময় মোবাইল অ্যাপ্লিকেশনগুলো সঠিকভাবে কাজ করার জন্য একটি সক্রিয় ইন্টারনেট কানেকশনের প্রয়োজন হয়। তবে, ইন্টারনেট কানেকশন হারানো স্বাভাবিক। ऐसे কেসগুলোতে, ডেভেলপারের দায়িত্ব تجربবহ করা বা কমপক্ষে ব্যবহারকারীকে জানানো।
এই নিবন্ধে, আমরা দেখব কীভাবে Swift-এ ইন্টারনেট কানেকশন সমস্যা সনাক্ত করা যায়, এবং কিছু উপায় যেগুলো দিয়ে এটি হ্যান্ডেল করা যায়।
এখানে আমরা যে স্যাম্পল অ্যাপ্লিকেশন বিল্ড করব এবং কীভাবে এটি বিভিন্ন ইন্টারনেট কানেক্টিভিটি সিনেরিও হ্যান্ডেল করে:

প্রয়োজনীয়তা
এই নিবন্ধটি ফলো করার জন্য, আপনার নিচের প্রয়োজনীয়তাগুলো থাকতে হবে:
- আপনার মেশিনে Xcode ইনস্টল করা।
- Swift প্রোগ্রামিং ভাষার জ্ঞান।
- আপনার মেশিনে CocoaPods ইনস্টল করা।
যদি উপরের প্রয়োজনীয়তাগুলো থাকে, চলুন শুরু করি।
ওয়ার্কস্পেস সেট আপ করা
শুরু করার আগে, আমরা একটি প্লেগ্রাউন্ড তৈরি করব। এটি হলো যেখানে আমরা আমাদের সব ইউজ কেস লিখব এবং হ্যান্ডেল করব।
Swift-এর নিজস্ব Reachability ইমপ্লিমেন্টেশন রয়েছে কানেকশন সমস্যা সনাক্ত করার জন্য, কিন্তু আমরা একটি থার্ড-পার্টি লাইব্রেরি ব্যবহার করব। আমরা এটি করছি কারণ এটি সহজ এবং API বেশি এক্সপ্রেসিভ বিল্ট-ইনটির চেয়ে।
Xcode খুলুন এবং একটি নতুন প্রোজেক্ট সেট আপ করুন।

এই প্রোজেক্টটি একটি সিম্পল প্লেগ্রাউন্ড হবে যা আমরা এক্সপেরিমেন্টের জন্য ব্যবহার করব।
কানেকশন অফলাইন হলে সনাক্ত করার জন্য আমরা Reachability.swift **প্যাকেজ ব্যবহার করব। এটি "Apple-এর Reachability-এর একটি রিপ্লেসমেন্ট, Swift-এ ক্লোজারসহ রি-রিটেন করা"।
আপনার টার্মিনাল খুলুন এবং নিচের কমান্ডটি চালান:
$ pod init এটি একটি নতুন Podfile তৈরি করবে যেখানে আমরা CocoaPods ডিপেন্ডেন্সি ডিক্লেয়ার করতে পারি। Podfile খুলুন এবং কন্টেন্টস নিচের কোড দিয়ে রিপ্লেস করুন:
platform :ios, '9.0' target 'project_name' do use_frameworks! pod 'ReachabilitySwift' pod 'Alamofire'end আপনাকে **project_name** আপনার প্রোজেক্টের নাম দিয়ে রিপ্লেস করতে হবে।
ফাইলটি সেভ করুন এবং আপনার প্রোজেক্টের রুটে নিচের কমান্ডটি চালান পডস ইনস্টল করার জন্য:
$ 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 নামে হবে। আমরা স্টোরiboard-এর প্রথম কন্ট্রোলার ভিউকে লঞ্চ কন্ট্রোলার হিসেবে বিবেচনা করব। আমরা চেষ্টা করব ব্যবহারকারীর ডিভাইস অনলাইন কিনা সনাক্ত করতে, এবং যদি না হয়, আমরা একটি অফলাইন পেজ তৈরি করব এটি হ্যান্ডেল করার জন্য যাতে ব্যবহারকারী অ্যাপ্লিকেশনের ভিতরে কখনো না যায়।
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 সেট করুন।
এরপর, স্টোরiboard-এ একটি নতুন ভিউ কন্ট্রোলার তৈরি করুন। এই নতুন ভিউ কন্ট্রোলারের জন্য OfflineViewController কাস্টম ক্লাস হিসেবে সেট করুন। এখন NetworkUnavailable নামে একটি ম্যানুয়াল সেগুই তৈরি করুন নতুন ভিউ কন্ট্রোলার এবং LaunchViewController-এর মধ্যে। কাজ শেষ হলে আপনার কাছে কিছু এমন থাকবে:

এখন অ্যাপ্লিকেশনটি রান করুন। নোট করুন, অ্যাপ্লিকেশন রান করার আগে, আপনার ডেভেলপমেন্ট মেশিন অফলাইন থাকতে হবে কারণ iOS সিমুলেটর মেশিনের ইন্টারনেট কানেকশন ব্যবহার করে। অ্যাপ্লিকেশন রান করলে, আপনাকে আমাদের তৈরি করা অফলাইন পেজটি দেখাবে।
এখন চলুন একটি ভিউ কন্ট্রোলার তৈরি করি যা কানেকশন থাকলে দেখাবে।
ডিভাইস অনলাইন হলে ইভেন্ট হ্যান্ডল করা
এখন যেহেতু আমরা একটি Offline View Controller তৈরি করেছি এবং এটি ডিভাইস অফলাইন থাকলে কাজ করে, চলুন হ্যান্ডেল করি কী ঘটে যখন ডিভাইস আবার অনলাইন হয়।
স্টোরiboard-এ Offline View Controller-এর নিচে একটি নতুন নেভিগেশন ভিউ কন্ট্রোলার তৈরি করুন। আমরা একটি কন্ট্রোলার তৈরি করব যা লেটেস্ট Reddit পোস্টগুলো দেখাবে। একটি নতুন ভিউ কন্ট্রোলার ক্লাস তৈরি করুন PostsTableViewController নামে। এখন নেভিগেশন ভিউ কন্ট্রোলারের সাথে যুক্ত ভিউ কন্ট্রোলারের জন্য এটি কাস্টম ক্লাস করুন।
এখন MainController নামে একটি ম্যানুয়াল সেগুই তৈরি করুন নেভিগেশন ভিউ কন্ট্রোলার থেকে লঞ্চ ভিউ কন্ট্রোলার এবং অফলাইন ভিউ কন্ট্রোলার পর্যন্ত। আপনার কাছে কিছু এমন থাকবে:

এখন, 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 মেথডও ওভাররাইড করেছি নেভিগেশন বার অফলাইন ভিউ কন্ট্রোলারে দেখাবেন না সেটি নিশ্চিত করার জন্য।
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 পোস্ট দেখার সময়, আপনি কানেক্টিভিটি হারিয়ে ফেললেন। কী হবে? চলুন আবার অফলাইন পেজ দেখান যখন এটা হয়।
যেমন আগে করা হয়েছিল, PostsTableViewController থেকে OfflineViewController-এ NetworkUnavailable নামে একটি ম্যানুয়াল সেগুই তৈরি করুন। এখন viewDidLoad মেথডের নিচে এই কোডটি যোগ করুন:
network.reachability.whenUnreachable = { reachability in self.showOfflinePage()} এখন কন্ট্রোলারে নিচের মেথডটি যোগ করুন:
private func showOfflinePage() -> Void { DispatchQueue.main.async { self.performSegue(withIdentifier: "NetworkUnavailable", sender: self) }} এটি ডিভাইস অফলাইন হলে লিসেন করবে এবং, যদি এটা হয়, এটি showOfflinePage করবে।
এটিই ছিল সব! আমরা আমাদের NetworkManager-এ Swift-এ অফলাইন এবং অনলাইন ইভেন্ট হ্যান্ডেল করতে সক্ষম হয়েছি।
উপসংহার
এই নিবন্ধে, আমরা বিবেচনা করেছি কীভাবে নিশ্চিত করতে হয় আপনার অ্যাপ্লিকেশন অনলাইন এবং অফলাইন ইভেন্ট হ্যান্ডেল করতে পারে যখন সেগুলো ঘটে। আপনি যেকোনো উপায়ে এটি ইমপ্লিমেন্ট করতে পারেন। আপনার কোনো প্রশ্ন বা ফিডব্যাক থাকলে, নিচে কমেন্টে লিখুন।
এই প্লেগ্রাউন্ডের সোর্স কোড GitHub-এ উপলব্ধ।
এই নিবন্ধটি প্রথমে Pusher-এ পাবলিশ হয়েছিল।
Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started