xcode: проверка наличия интернет на устройстве и вывод локального html в wkwebview
Задача: при обнаружении отсутствия интернет на устройстве вывести в виджет wkwebview уведомление о его отсутствии оформленное в виде HTML страницы
Решение:
1) Создадим файл Reachability.swift с классом,отдающим доступность:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
import Foundation import SystemConfiguration let ReachabilityStatusChangedNotification = "ReachabilityStatusChangedNotification" enum ReachabilityType: CustomStringConvertible { case wwan case wiFi var description: String { switch self { case .wwan: return "WWAN" case .wiFi: return "WiFi" } } } enum ReachabilityStatus: CustomStringConvertible { case offline case online(ReachabilityType) case unknown var description: String { switch self { case .offline: return "Offline" case .online(let type): return "Online (\(type))" case .unknown: return "Unknown" } } } public class Reach { func connectionStatus() -> ReachabilityStatus { var zeroAddress = sockaddr_in() zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size) zeroAddress.sin_family = sa_family_t(AF_INET) guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, { $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil, $0) } }) else { return .unknown } var flags : SCNetworkReachabilityFlags = [] if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { return .unknown } return ReachabilityStatus(reachabilityFlags: flags) } func monitorReachabilityChanges() { let host = "google.com" var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) let reachability = SCNetworkReachabilityCreateWithName(nil, host)! SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in let status = ReachabilityStatus(reachabilityFlags: flags) NotificationCenter.default.post(name: Notification.Name(rawValue: ReachabilityStatusChangedNotification), object: nil, userInfo: ["Status": status.description]) }, &context) SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), RunLoop.Mode.common as CFString) } } extension ReachabilityStatus { init(reachabilityFlags flags: SCNetworkReachabilityFlags) { let connectionRequired = flags.contains(.connectionRequired) let isReachable = flags.contains(.reachable) let isWWAN = flags.contains(.isWWAN) if !connectionRequired && isReachable { if isWWAN { self = .online(.wwan) } else { self = .online(.wiFi) } } else { self = .offline } } } |
В основной код добавим слушатель изменения состояния сети и отдающий html страницу при отсутствии интернет:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
override func viewDidLoad() { super.viewDidLoad() webview.allowsBackForwardNavigationGestures=false; //webview.navigationDelegate = self NotificationCenter.default.addObserver(self, selector: #selector(ViewController.networkStatusChanged(_:)), name: Notification.Name(rawValue: ReachabilityStatusChangedNotification), object: nil) Reach().monitorReachabilityChanges() webview.load(URLRequest(url: URL(string:"https://цувцувц.ru")!)); } @objc func networkStatusChanged(_ notification: Notification) { if let userInfo = notification.userInfo { let status = userInfo["Status"] as! String if (status=="Offline") { webview.loadHTMLString( "<html><body><p>Offline</p></body></html>", baseURL: nil ) } } } |
Вставляем в проект локальную папку с файлом html и файлом картинки:
И изменим код следующим образом:
1 2 3 4 |
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "localhtml")! webview.loadFileURL(url, allowingReadAccessTo: url) let request = URLRequest(url: url) webview.load(request) |