我使用下面的代码在服务器中发出HTTP请求。现在我想知道它是否连接到互联网。以下是我的代码
let request = Alamofire.request(completeURL(domainName: path), method: method, parameters: parameters, encoding: encoding.value, headers: headers)
.responseJSON {
let resstr = NSString(data: $0.data!, encoding: String.Encoding.utf8.rawValue)
print("error is \(resstr)")
if $0.result.isFailure {
self.failure("Network")
print("API FAILED 4")
return
}
guard let result = $0.result.value else {
self.unKnownError()
self.failure("")
print("API FAILED 3")
return
}
self.handleSuccess(JSON(result))
}
对于swift 3.1和Alamofire 4.4,我创建了一个名为Connectivity
的快速类。根据您的需要,使用NetworkReachabilityManager
的Alamofire
类和configure
的isConnectedToInternet()
方法。
import Foundation
import Alamofire
class Connectivity {
class func isConnectedToInternet() -> Bool {
return NetworkReachabilityManager()?.isReachable ?? false
}
}
用法:
if Connectivity.isConnectedToInternet() {
print("Yes! internet is available.")
// do some tasks..
}
编辑:由于swift鼓励计算属性,您可以更改上面的函数,如:
import Foundation
import Alamofire
class Connectivity {
class var isConnectedToInternet:Bool {
return NetworkReachabilityManager()?.isReachable ?? false
}
}
并使用它像:
if Connectivity.isConnectedToInternet {
print("Yes! internet is available.")
// do some tasks..
}
斯威夫特2.3
Alamofire.request(.POST, url).responseJSON { response in
switch response.result {
case .Success(let json):
// internet works.
case .Failure(let error):
if let err = error as? NSURLError where err == .NotConnectedToInternet {
// no internet connection
} else {
// other failures
}
}
}
Swift 3.0
Alamofire.upload(multipartFormData: { multipartFormData in
}, to: URL, method: .post,headers: nil,
encodingCompletion: { (result) in
switch result {
case .success( _, _, _): break
case .failure(let encodingError ):
print(encodingError)
if let err = encodingError as? URLError, err.code == .notConnectedToInternet {
// no internet connection
print(err)
} else {
// other failures
}
}
})
使用NetworkReachabilityManager
let networkReachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.apple.com")
func checkForReachability() {
self.networkReachabilityManager?.listener = { status in
print("Network Status: \(status)")
switch status {
case .notReachable:
//Show error here (no internet connection)
case .reachable(_), .unknown:
//Hide error here
}
}
self.networkReachabilityManager?.startListening()
}
//How to Use : Just call below function in required class
if checkForReachability() {
print("connected with network")
}
对于Swift 3/4,
在Alamofire,有一个名为NetworkReachabilityManager
的类,可用于观察或检查互联网是否可用。
let reachabilityManager = NetworkReachabilityManager()
reachabilityManager?.startListening()
reachabilityManager?.listener = { _ in
if let isNetworkReachable = self.reachabilityManager?.isReachable,
isNetworkReachable == true {
//Internet Available
} else {
//Internet Not Available"
}
}
在这里,每次互联网状态发生变化时,都会调用监听器。你可以按照自己的意愿处理它。
如果你去NetworkReachabilityManager.swift
你会看到这个
///网络当前是否可访问public var isReachable:Bool {return isReachableOnWWAN || isReachableOnEthernetOrWiFi}
所以我在我的APIhandlerClass中写了这个
import AlamofireNetworkActivityIndicator
private let manager = NetworkReachabilityManager(host: "www.apple.com")
func isNetworkReachable() -> Bool {
return manager?.isReachable ?? false
}
所以这告诉我网络的状态。
func isConnectedToNetwork()-> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
//Commented code only work upto iOS Swift 2.3
// let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
//
// SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
// }
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)
}
// Call api method
func callApi(){
if isConnectedToNetwork() { // Network Connection status
// Call your request here
}else{
//"Your Internet connection is not active at this time."
}
}
如果Alamofire.upload结果返回成功,则下面是在上传图像时检查互联网可用性的方法:
Alamofire.upload(multipartFormData: { multipartFormData in
for (key,value) in parameters {
multipartFormData.append((value).data(using: .utf8)!, withName: key)
}
multipartFormData.append(self.imageData!, withName: "image" ,fileName: "image.jpg" , mimeType: "image/jpeg")
}, to:url)
{ (result) in
switch result{
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if let statusCode = response.response?.statusCode{
if(statusCode == 201){
//internet available
}
}else{
//internet not available
}
}
case .failure(let encodingError):
print(encodingError)
}
}
RequestAdapter
类的alamofire并在没有互联网连接时抛出错误class RequestInterceptor : RequestAdapter{
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
let reachable = NetworkReachabilityManager()?.isReachable ?? false
if !reachable{
throw NSError.NoInternet
}
var nUrlRequest = urlRequest
// modify request if needed
return nUrlRequest
}
}
extension NSError {
static func createWithLocalizedDesription(withCode code:Int = 204,localizedDescription:String) -> NSError{
return NSError(domain: "<your bundle id>", code:code, userInfo: [NSLocalizedDescriptionKey : localizedDescription])
}
static var NoInternet : NSError {
return createWithLocalizedDesription(withCode: -1009,localizedDescription:"Please check your internet connection")
}
}
现在将适配器设置为Alamofire Session Manager
let sessionManager = Alamofire.SessionManager(configuration: configuration)
sessionManager.adapter = RequestInterceptor()
现在每次创建Alamofire请求时,都会捕获DataResponse中的错误。这种机制对所有请求都是通用的
一般情况下,如果您可以从实际呼叫中获取互联网离线信息,则其优于可达性。您可以确定实际的API调用已失败,因为互联网已关闭。如果你在调用API之前测试可达性并且它失败了那么你所知道的是,当测试完成后互联网处于脱机状态(或Apple已关闭)时,你不知道当你拨打电话时互联网将是离线。您可能认为在可达性调用返回后几毫秒,或者您检索了存储的值,但这实际上是非确定性的。在可达性在其闭包中返回其值之前,操作系统可能已经安排了一些任意数量的线程,或者更新了您正在存储的全局数据。
可达性在历史上一直存在自己的代码中的错误。
这并不是说您不应该使用alamofire的NetworkReachabilityManager来更改UI,收听它并更新所有UI组件。
但是如果您有理由调用API,那么在该API层上,可达性测试是多余的,或者可能会导致一些微妙的错误。