网络连接检查在Swift中的IPv6网络上崩溃

时间:2016-07-22 01:47:34

标签: ios swift ipv6

我最近因不与IPv6兼容而被拒绝了应用。调用以下代码时,应用程序导致崩溃。我怀疑崩溃是因为当Apple建议不再使用它时它会使用new StructuredArray...

任何人都可以帮我一把,并帮助使下面的代码兼容IPv6和IPv4吗?

代码

SCNetworkReachabilityCreateWithAddress

代码来源:

Check for internet connection availability in Swift

视图上的代码调用已加载:

import Foundation
import SystemConfiguration

public class Reachability {

    class func isConnectedToNetwork() -> Bool {

        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)

        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
        }

        var flags: SCNetworkReachabilityFlags = 0
        if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
            return false
        }

        let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

        return isReachable && !needsConnection
    }

}

4 个答案:

答案 0 :(得分:1)

您正在崩溃,因为您在该代码中显示应该在主UI线程中运行的警报。将您的UI代码放入dispatch_async进入主UI线程,它应该解决问题。

dispatch_async(dispatch_get_main_queue(),
{
   let error = NSError(domain: "", code: 3, userInfo: nil)           let alertView = createDefaultAlertError(error.code)
      let tryAgainAction = UIAlertAction(title: ClassGeneralMessages().userMessageTryAgain, style: UIAlertActionStyle.Default) { (UIAlertAction) in }
})

答案 1 :(得分:1)

来自Apple's documentation on supporting IPv6-only networks

  

不使用预检连接

     

可识别性API(请参阅SCNetworkReachability Reference)用于在识别连接问题后进行诊断。许多应用程序错误地使用这些API通过调用SCNetworkReachabilityCreateWithAddress方法并将其传递给0.0.0.0的IPv4地址来主动检查Internet连接,这表明网络上有路由器。但是,路由器的存在并不能保证存在Internet连接。通常,避免预检网络可达性。只是尝试建立连接并优雅地处理故障。如果必须检查网络可用性,请避免调用SCNetworkReachabilityCreateWithAddress方法。调用SCNetworkReachabilityCreateWithName方法并将其传递给主机名。

您的应用似乎正在执行以下建议:

  1. 使用可访问性API执行预检,而不仅仅是在出现连接问题时。
  2. 将IPv4文字传递给可访问性API而不是主机名。
  3. 为了解决这个问题,我建议不要事先检查网络连接,而是要处理网络代码中的错误。

答案 2 :(得分:1)

试试这个:

class func isConnectedToNetwork() -> Bool
        {
            var zeroAddress = sockaddr_in6()
            zeroAddress.sin6_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
            zeroAddress.sin6_family = sa_family_t(AF_INET6)

            let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
                $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                    SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
                }
            }

            var flags = SCNetworkReachabilityFlags()
            if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
                return false
            }
            let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
            let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
            return (isReachable && !needsConnection)
        }

答案 3 :(得分:0)

newArray = ['John','Alex','Sophia','Rick']

a = str(raw_input('Type your name if you want to delete : '))
if a in newArray:
    for i in range(len(newArray)):
        if newArray[i]==a:
            del newArray[i] # I want to delete it
        else:
            print newArray[i]   

}