我想知道是否有一种方法可以让UIWebView在离线时透视。我想为这个应用程序显示一个"你需要互联网"它背后的文字,以便当你没有互联网访问时显示它。这可能吗?
任何帮助表示赞赏! :)
答案 0 :(得分:0)
使用while在网络连接脱机时继续观看。当它处于脱机状态时,隐藏UIWebView并在其后面显示相同大小的UILabel。反之亦然,当网络连接时。
答案 1 :(得分:0)
通常您可以直接从官方苹果网站下载Reachability,但我会将Ashley Mills提供的快速翻译转发给他的github page(如果不可用,请在Rechability.swift的副本下方) 。您必须在项目中导入此文件。
正如你所看到的那样几行。我为UIViewController
做了一个示例,但您可以在UIWebViewController
或您想要的任何地方实现它:
let reachability = Reachability.reachabilityForInternetConnection()
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(ViewController.checkReachability(_:)), name: ReachabilityChangedNotification, object: reachability)
reachability?.startNotifier()
}
func checkReachability(note: NSNotification) {
reachability?.startNotifier()
if reachability!.isReachable() {
if reachability!.isReachableViaWiFi() {
print("∙ reachability via WIFI enabled")
} else {
print("∙ reachability via 3G/4G enabled")
}
} else {
print("∙ network is unreachable..")
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let alert = UIAlertController(title: "No internet", message:"No internet connection available!", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default) { _ in })
appDelegate.window?.rootViewController?.presentViewController(alert, animated: true){}
// Here you can put also a label, or an HTML page to show "no internet connection", do whatever you want to alert your connection status
}
}
Reachability.swift的副本:
import SystemConfiguration
import Foundation
public let ReachabilityChangedNotification = "ReachabilityChangedNotification"
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let reachability = Unmanaged<Reachability>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
dispatch_async(dispatch_get_main_queue()) {
reachability.reachabilityChanged(flags)
}
}
public class Reachability: NSObject {
public typealias NetworkReachable = (Reachability) -> ()
public typealias NetworkUnreachable = (Reachability) -> ()
public enum NetworkStatus: CustomStringConvertible {
case NotReachable, ReachableViaWiFi, ReachableViaWWAN
public var description: String {
switch self {
case .ReachableViaWWAN:
return "Cellular"
case .ReachableViaWiFi:
return "WiFi"
case .NotReachable:
return "No Connection"
}
}
}
// MARK: - *** Public properties ***
public var whenReachable: NetworkReachable?
public var whenUnreachable: NetworkUnreachable?
public var reachableOnWWAN: Bool
public var notificationCenter = NSNotificationCenter.defaultCenter()
public var currentReachabilityStatus: NetworkStatus {
if isReachable() {
if isReachableViaWiFi() {
return .ReachableViaWiFi
}
if isRunningOnDevice {
return .ReachableViaWWAN
}
}
return .NotReachable
}
public var currentReachabilityString: String {
return "\(currentReachabilityStatus)"
}
// MARK: - *** Initialisation methods ***
required public init?(reachabilityRef: SCNetworkReachability?) {
reachableOnWWAN = true
self.reachabilityRef = reachabilityRef
}
public convenience init?(hostname: String) {
let nodename = (hostname as NSString).UTF8String
let ref = SCNetworkReachabilityCreateWithName(nil, nodename)
self.init(reachabilityRef: ref)
}
public class func reachabilityForInternetConnection() -> Reachability? {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let ref = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
return Reachability(reachabilityRef: ref)
}
public class func reachabilityForLocalWiFi() -> Reachability? {
var localWifiAddress: sockaddr_in = sockaddr_in(sin_len: __uint8_t(0), sin_family: sa_family_t(0), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
localWifiAddress.sin_len = UInt8(sizeofValue(localWifiAddress))
localWifiAddress.sin_family = sa_family_t(AF_INET)
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
let address: UInt32 = 0xA9FE0000
localWifiAddress.sin_addr.s_addr = in_addr_t(address.bigEndian)
let ref = withUnsafePointer(&localWifiAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
return Reachability(reachabilityRef: ref)
}
// MARK: - *** Notifier methods ***
public func startNotifier() -> Bool {
if notifierRunning { return true }
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())
if SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
if SCNetworkReachabilitySetDispatchQueue(reachabilityRef!, reachabilitySerialQueue) {
notifierRunning = true
return true
}
}
stopNotifier()
return false
}
public func stopNotifier() {
if let reachabilityRef = reachabilityRef {
SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
}
notifierRunning = false
}
// MARK: - *** Connection test methods ***
public func isReachable() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isReachableWithFlags(flags)
})
}
public func isReachableViaWWAN() -> Bool {
if isRunningOnDevice {
return isReachableWithTest() { flags -> Bool in
// Check we're REACHABLE
if self.isReachable(flags) {
// Now, check we're on WWAN
if self.isOnWWAN(flags) {
return true
}
}
return false
}
}
return false
}
public func isReachableViaWiFi() -> Bool {
return isReachableWithTest() { flags -> Bool in
// Check we're reachable
if self.isReachable(flags) {
if self.isRunningOnDevice {
// Check we're NOT on WWAN
if self.isOnWWAN(flags) {
return false
}
}
return true
}
return false
}
}
// MARK: - *** Private methods ***
private var isRunningOnDevice: Bool = {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return false
#else
return true
#endif
}()
private var notifierRunning = false
private var reachabilityRef: SCNetworkReachability?
private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL)
private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
if isReachableWithFlags(flags) {
if let block = whenReachable {
block(self)
}
} else {
if let block = whenUnreachable {
block(self)
}
}
notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
}
private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
let reachable = isReachable(flags)
if !reachable {
return false
}
if isConnectionRequiredOrTransient(flags) {
return false
}
if isRunningOnDevice {
if isOnWWAN(flags) && !reachableOnWWAN {
// We don't want to connect when on 3G.
return false
}
}
return true
}
private func isReachableWithTest(test: (SCNetworkReachabilityFlags) -> (Bool)) -> Bool {
if let reachabilityRef = reachabilityRef {
var flags = SCNetworkReachabilityFlags(rawValue: 0)
let gotFlags = withUnsafeMutablePointer(&flags) {
SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
}
if gotFlags {
return test(flags)
}
}
return false
}
// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
private func isConnectionRequired() -> Bool {
return connectionRequired()
}
private func connectionRequired() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags)
})
}
// Dynamic, on demand connection?
private func isConnectionOnDemand() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags) && self.isConnectionOnTrafficOrDemand(flags)
})
}
// Is user intervention required?
private func isInterventionRequired() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags) && self.isInterventionRequired(flags)
})
}
private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
#if os(iOS)
return flags.contains(.IsWWAN)
#else
return false
#endif
}
private func isReachable(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.Reachable)
}
private func isConnectionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionRequired)
}
private func isInterventionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.InterventionRequired)
}
private func isConnectionOnTraffic(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnTraffic)
}
private func isConnectionOnDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnDemand)
}
func isConnectionOnTrafficOrDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return !flags.intersect([.ConnectionOnTraffic, .ConnectionOnDemand]).isEmpty
}
private func isTransientConnection(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.TransientConnection)
}
private func isLocalAddress(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsLocalAddress)
}
private func isDirect(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsDirect)
}
private func isConnectionRequiredOrTransient(flags: SCNetworkReachabilityFlags) -> Bool {
let testcase:SCNetworkReachabilityFlags = [.ConnectionRequired, .TransientConnection]
return flags.intersect(testcase) == testcase
}
private var reachabilityFlags: SCNetworkReachabilityFlags {
if let reachabilityRef = reachabilityRef {
var flags = SCNetworkReachabilityFlags(rawValue: 0)
let gotFlags = withUnsafeMutablePointer(&flags) {
SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
}
if gotFlags {
return flags
}
}
return []
}
override public var description: String {
var W: String
if isRunningOnDevice {
W = isOnWWAN(reachabilityFlags) ? "W" : "-"
} else {
W = "X"
}
let R = isReachable(reachabilityFlags) ? "R" : "-"
let c = isConnectionRequired(reachabilityFlags) ? "c" : "-"
let t = isTransientConnection(reachabilityFlags) ? "t" : "-"
let i = isInterventionRequired(reachabilityFlags) ? "i" : "-"
let C = isConnectionOnTraffic(reachabilityFlags) ? "C" : "-"
let D = isConnectionOnDemand(reachabilityFlags) ? "D" : "-"
let l = isLocalAddress(reachabilityFlags) ? "l" : "-"
let d = isDirect(reachabilityFlags) ? "d" : "-"
return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)"
}
deinit {
stopNotifier()
reachabilityRef = nil
whenReachable = nil
whenUnreachable = nil
}
}
答案 2 :(得分:-1)
这样做的一个非常简单的方法如下:
nointernet.html
,将此文件添加到您的项目中。
<html>
<body>
</br></br></br></br></br></br>
<p>You need internet connection to use this application.</p>
</body>
</html>
在下面实施UIWebView
委托方法:
- shouldStartLoadWithRequest:navigationType:
- didFailLoadWithError:
在webView?.delegate = self
方法
viewDidLoad
现在没有互联网连接时,将调用webView的didFailLoadWithError
委托方法。写下以下代码,以显示来自HTML文件的“无互联网连接”消息。
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
return true
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
print("Did fail to load")
let htmlFilePath : String! = NSBundle.mainBundle() .pathForResource("nointernet", ofType: "html")
if let htmlString = try? String(contentsOfFile: htmlFilePath!) {
webView.loadHTMLString(htmlString, baseURL: NSBundle.mainBundle().bundleURL)
}
}