I have three custom swift classes in my app. One is a NetworkServices
class and the other two are custom UIViewController
classes. The NetworkServices class posts a notification to the other two classes when wifi is turned on and there is a.network connection and also when wifi is turned off and there is no.network connection. Currently, the app starts up posting the isConnected
notification and code executes as expected. I then turn off wifi and isDisconnected
is posted and code executes as expected. However, when I then turn wifi back on again the isConnected
post is sent but it is not received by either of the two custom UIViewController
classes. My problem is why not?
here are relevant lines of code in my NetworkServices
class;
protocol NetworkServicesDelegate: AnyObject {
func sendStockInfo(stocksInfo: [String: StockInfo])
}
final class NetworkServices {
static let sharedInstance = NetworkServices()
...
public func startMonitoring() {
monitor.start(queue: queue)
self.monitor.pathUpdateHandler = { [weak self] path in
if path.status == .satisfied {
// connect the socket
self?.socket.connect()
print("DEBUG: self?.socket.connect() called")
} else {
// disconnect the socket
self?.socket.disconnect()
// print("DEBUG: self?.socket.disconnect() called")
self?.isConnected = false
// post notification that socket is now disconnected
DispatchQueue.main.async {
print("DEBUG: Notification.Name(rawValue) called")
let name = Notification.Name(rawValue: isDisconnectedNotificationKey)
NotificationCenter.default.post(name: name, object: nil)
}
}
}
}
...
}
extension NetworkServices: WebSocketDelegate {
func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected(_):
self.isConnected = true
// post notification that socket is now connected
let name = Notification.Name(rawValue: isConnectedNotificationKey)
NotificationCenter.default.post(name: name, object: nil)
print("DEBUG: Notification isConnected posted")
case .disconnected(let reason, let code):
print("DEBUG: Got disconnected reason = \(reason) code = \(code)")
self.isConnected = false
case .cancelled:
print("DEBUG: cancelled.")
// reconnect socket
socket.connect()
self.isConnected = true
case .reconnectSuggested(let suggestReconnect):
print("DEBUG: suggestReconnect = \(suggestReconnect)")
// post notification that socket is not connected
case .viabilityChanged(let viabilityChanged):
print("DEBUG: viabilityChanged = \(viabilityChanged)")
case .error(let error):
print("DEBUG error: \(String(describing: error?.localizedDescription))")
case .text(let socketString):
// print("DEBUG: .text available")
parseJSONSocketData(socketString)
default:
break
}
}
}
Here are the relevant lines of code from my two custom UIViewController
classes;
protocol CompanyPriceListDelegate: AnyObject {
func sendPriceHistory(_ priceHistory: PriceHistory)
}
class CompanyPriceListVC: UITableViewController {
...
let isConnected = Notification.Name(rawValue: isConnectedNotificationKey)
let isNotConnected = Notification.Name(rawValue: isDisconnectedNotificationKey)
override func viewDidLoad() {
super.viewDidLoad()
...
createObservers()
...
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func createObservers() {
print("DEBUG: createObservers() called")
NotificationCenter.default.addObserver(self, selector: #selector(CompanyPriceListVC.dismissAndFetchStockInfo), name: isConnected, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(CompanyPriceListVC.notifyUserOnScreen(notification:)), name: isNotConnected, object: nil)
}
@objc private func fetchStockInfo() {
NetworkServices.sharedInstance.fetchStockInfo(symbols: companyStockSymbols, delegate: self)
}
@objc private func notifyUserOnScreen(notification: NSNotification) {
self.present(alertController, animated: true)
}
@objc public func dismissAndFetchStockInfo() {
if presentedViewController == alertController {
self.alertController.dismiss(animated: true, completion: nil)
}
fetchStockInfo()
}
...
}
//
// CompanyDetailsVC.swift
// BetVictorTask
//
// Created by Stephen Learmonth on 02/03/2022.
//
import UIKit
class CompanyDetailsVC: UIViewController {
...
let isConnected = Notification.Name(rawValue: isConnectedNotificationKey)
let isNotConnected = Notification.Name(rawValue: isDisconnectedNotificationKey)
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationBar()
addSubViews()
activateConstraints()
createObservers()
fetchCompanyDetails(symbol: symbol)
let controller = navigationController?.viewControllers.first as! CompanyPriceListVC
controller.delegate = self
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func createObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(CompanyDetailsVC.dismissAndFetchCompanyDetails), name: isConnected, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(CompanyDetailsVC.notifyUserOnScreen(notification:)), name: isNotConnected, object: nil)
}
@objc private func dismissAndFetchCompanyDetails() {
print("DEBUG: dismissAndFetchCompanyDetails() called")
if presentedViewController == alertController {
self.alertController.dismiss(animated: true, completion: nil)
}
fetchCompanyDetails(symbol: symbol)
}
@objc private func notifyUserOnScreen(notification: NSNotification) {
print("DEBUG: notifyUserOnScreen(notification) called")
self.present(alertController, animated: true)
}
...
}
extension CompanyDetailsVC: CompanyPriceListDelegate {
func sendPriceHistory(_ priceHistory: PriceHistory) {
self.updatePrices(priceHistory)
}
}
I'm testing on a real device.
Removed socket.connect() from the.cancelled case
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.