在Swift iOS 9.3中检查速度是否较慢(不仅仅是设备是否已连接)

Stj*_*pan 5 ios swift alamofire

互联网连接速度非常慢时,我在处理该案件时遇到了一些麻烦。首先,让我解释一下。当设备未连接到Internet时,我可以处理以下功能:

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(kCFAllocatorDefault, UnsafePointer($0))
        }

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

        let isReachable = flags == .Reachable
        let needsConnection = flags == .ConnectionRequired

        return isReachable && !needsConnection
    }
Run Code Online (Sandbox Code Playgroud)

因此,当设备连接到Internet且连接快速稳定时,一切正常。当设备未连接到Internet时,我会收到警告,我需要连接并且也得到了处理。

问题是,当我连接并且互联网非常缓慢时,例如16 kbps。Alamofire要求提供许多功能,并且以这种速度下载需要花费数年的时间。如果它没有停止我的应用程序并最终使其崩溃,我也不介意。

我试过这个功能:

class func isInternetActive(input: String, completion: (result: String) -> Void)
    {
        let qualityOfServiceClass = QOS_CLASS_BACKGROUND
        let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
        dispatch_async(backgroundQueue, {

            Alamofire.request(.GET, "http://www.google.hr").response
                { response in
                    if response.3 != nil
                    {
                        print("NOK")
                        completion(result: "NOK")
                    }
                    print("OK")
                    completion(result: "OK")
            }
        })

    }
Run Code Online (Sandbox Code Playgroud)

另外,我正在使用Alamofire为我的社交媒体视图控制器和Twitter获取数据,而我正在使用Fabric。

我想要这样的东西:尝试获取数据。如果您无法在3-4秒内拿到它们。然后停止请求。因此,如果您无法在几秒钟内下载图像,则让该imageView为白色或空白,就像我没有连接到Internet时一样。

小智 1

我解决了这个问题。我通过 Alamofire 请求一个 img URL,然后使用代码设置图像(使用该 url),例如:

var url:NSURL = NSURL.URLWithString("http://myURL/ios8.png")
var data:NSData = NSData.dataWithContentsOfURL(url, options: nil, error: nil)
Run Code Online (Sandbox Code Playgroud)

这就是问题所在。Alamofire在后台线程中,上面的代码在主线程中。因此,当 Alamofire 完成他的请求时,必须运行代码。

这是示例:

dispatch_async(dispatch_get_global_queue(qualityOfServiceClass, 0), {
            Alamofire.request(.GET, "http://blabla.com").responseJSON(completionHandler:
                { (json) -> Void in
                    if let jsonData = json.result.value
                    {
                        if jsonData.isKindOfClass(NSArray)
                        {
                            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                                let secondImageURLL = jsonData[x][ImgURL] as! String
                                setImageToUrlImageViewForHomeSlider(sliderData, imageToSetL: imageToSetL)
                            })
                        }
                    }
            })
        })
Run Code Online (Sandbox Code Playgroud)

这里可以看到请求在全局队列中,主队列中的代码必须等待后台队列完成,调用函数setImageToUrlImageViewForHomeSlider:

func setImageToUrlImageViewForHomeSlider(sliderDataL: WBMHomeSliderDataM, imageToSetL: UIImageView)
{
    let url = NSURL(string: sliderDataL.imageURL!)
    imageToSetL.sd_setImageWithURL(url, placeholderImage: UIImage(named: "cloudErrorHomeSlider"))
}
Run Code Online (Sandbox Code Playgroud)

在此函数中,我使用 SDWebImage 框架(也是异步运行的)来设置带有下载 URL 的图像,如果失败,则设置占位符图像。

这样,您的应用程序就可以免费加载,并且不会因为互联网连接速度慢而停止、冻结或崩溃。