ios - ¿Cómo comprobar la conexión a internet en alamofire?
swift reachability (8)
Swift 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
}
}
})
Utilizando 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")
}
Estoy utilizando el siguiente código para realizar una solicitud HTTP en el servidor. Ahora quiero saber si está conectado a Internet o no. Abajo esta mi codigo
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))
}
Uso de la clase RequestAdapter
de alamofire y error de lanzamiento cuando no hay conectividad a internet
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")
}
}
Ahora configura el adaptador a Alamofire Session Manager
let sessionManager = Alamofire.SessionManager(configuration: configuration)
sessionManager.adapter = RequestInterceptor()
Ahora, cada vez que cree una solicitud de Alamofire , detecte el error en DataResponse. Este mecanismo actuará común a toda solicitud.
En general, si puede obtener la información sin conexión a Internet de la llamada real, es mejor que la accesibilidad. Puede estar seguro de que la llamada a la API real ha fallado porque Internet está inactivo. Si realiza una prueba de accesibilidad antes de llamar a una API y falla, entonces todo lo que sabe es que cuando se realizó la prueba, Internet estaba fuera de línea (o Apple estaba fuera de servicio), no sabe que cuando realice la llamada, Internet será desconectado. Podría pensar que es cuestión de milisegundos después de que se devuelva la llamada de alcance, o que recupere el valor almacenado, pero eso no es determinista. Es posible que el sistema operativo haya programado un número arbitrario de subprocesos antes de que la accesibilidad devuelva sus valores en su cierre, o actualice lo que esté almacenando global.
Y la accesibilidad históricamente ha tenido errores en su propio código.
Esto no significa que no deba usar NetworkReachabilityManager de alamofire para cambiar su interfaz de usuario, escucharla y actualizar todos los componentes de la interfaz de usuario.
Pero si tiene motivos para llamar a una API, en esa capa de API, la prueba de accesibilidad es redundante, o posiblemente causará algunos errores sutiles.
Si el resultado de Alamofire.upload da como resultado un éxito, a continuación se muestra la forma de verificar la disponibilidad de Internet al cargar una imagen:
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)
}
}
Si vas a NetworkReachabilityManager.swift
verás esto
/// Si la red es accesible actualmente. public var isReachable: Bool {return isReachableOnWWAN || isReachableOnEthernetOrWiFi}
Así que he escrito esto en mi APIhandlerClass
import AlamofireNetworkActivityIndicator
private let manager = NetworkReachabilityManager(host: "www.apple.com")
func isNetworkReachable() -> Bool {
return manager?.isReachable ?? false
}
Así que esto me dice el estado de la red.
Para swift 3.1 y Alamofire 4.4 , creé una clase swift llamada Connectivity
. Use la clase NetworkReachabilityManager
de Alamofire
y configure
el método isConnectedToInternet()
según sus necesidades.
import Foundation
import Alamofire
class Connectivity {
class func isConnectedToInternet() -> Bool {
return NetworkReachabilityManager()?.isReachable ?? false
}
}
Uso:
if Connectivity.isConnectedToInternet() {
print("Yes! internet is available.")
// do some tasks..
}
EDITAR: Como swift está fomentando las propiedades computadas, puede cambiar la función anterior como:
import Foundation
import Alamofire
class Connectivity {
class var isConnectedToInternet:Bool {
return NetworkReachabilityManager()?.isReachable ?? false
}
}
y utilízalo como:
if Connectivity.isConnectedToInternet {
print("Yes! internet is available.")
// do some tasks..
}
Para Swift 3/4,
En Alamofire, hay una clase llamada NetworkReachabilityManager
que se puede usar para observar o verificar si Internet está disponible o no.
let reachabilityManager = NetworkReachabilityManager()
reachabilityManager?.startListening()
reachabilityManager?.listener = { _ in
if let isNetworkReachable = self.reachabilityManager?.isReachable,
isNetworkReachable == true {
//Internet Available
} else {
//Internet Not Available"
}
}
Aquí, el oyente será llamado cada vez que haya cambios en el estado de internet. Puedes manejarlo como quieras.
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."
}
}