J'utilise le code ci-dessous pour effectuer une requête HTTP dans server.Maintenant, je veux savoir s'il est connecté à Internet ou non. Ci-dessous mon code
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))
}
Pour Swift 3.1 et Alamofire 4.4, j'ai créé une classe Swift appelée Connectivity
. Utilisez NetworkReachabilityManager
class from Alamofire
et configure
la méthode isConnectedToInternet()
selon vos besoins.
import Foundation
import Alamofire
class Connectivity {
class func isConnectedToInternet() ->Bool {
return NetworkReachabilityManager()!.isReachable
}
}
Usage:
if Connectivity.isConnectedToInternet() {
print("Yes! internet is available.")
// do some tasks..
}
EDIT: Puisque Swift encourage les propriétés calculées, vous pouvez modifier la fonction ci-dessus comme suit:
import Foundation
import Alamofire
class Connectivity {
class var isConnectedToInternet:Bool {
return NetworkReachabilityManager()!.isReachable
}
}
et l'utiliser comme:
if Connectivity.isConnectedToInternet {
print("Yes! internet is available.")
// do some tasks..
}
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
}
}
})
Utilisation de 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")
}
Pour Swift 3/4,
Dans Alamofire, il existe une classe appelée NetworkReachabilityManager
qui peut être utilisée pour observer ou vérifier si Internet est disponible ou non.
let reachabilityManager = NetworkReachabilityManager()
reachabilityManager?.startListening()
reachabilityManager?.listener = { _ in
if let isNetworkReachable = self.reachabilityManager?.isReachable,
isNetworkReachable == true {
//Internet Available
} else {
//Internet Not Available"
}
}
Ici, l'auditeur sera appelé à chaque fois qu'il y a des changements dans l'état d'Internet. Vous pouvez le gérer comme vous le souhaitez.
Si vous passez au NetworkReachabilityManager.Swift
, vous verrez ceci
/// Si le réseau est actuellement accessible . public var isReachable: Bool {return isReachableOnWWAN || isReachableOnEthernetOrWiFi}
J'ai donc écrit ceci dans ma APIhandlerClass
import AlamofireNetworkActivityIndicator
private let manager = NetworkReachabilityManager(Host: "www.Apple.com")
func isNetworkReachable() -> Bool {
return manager?.isReachable ?? false
}
Donc, cela me dit le statut du réseau.
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."
}
}
RequestAdapter
de alamofire et erreur de projection en l'absence de connectivité Internetclass 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")
}
}
Configurez maintenant l'adaptateur sur Alamofire Session Manager
let sessionManager = Alamofire.SessionManager(configuration: configuration)
sessionManager.adapter = RequestInterceptor()
Maintenant, chaque fois que vous créez Demande Alamofire , interceptez l'erreur dans DataResponse. Ce mécanisme agira commun à toutes les demandes
Si Alamofire.upload result renvoie un succès, voici comment vérifier la disponibilité d'Internet lors du téléchargement d'une image:
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)
}
}
En général, si vous pouvez obtenir des informations hors ligne sur Internet à partir de l'appel, c'est mieux que l'accessibilité. Vous pouvez être certain que l'appel de l'API a échoué car Internet est en panne. Si vous testez l'accessibilité avant d'appeler une API et que celle-ci échoue, tout ce que vous savez, c'est que lorsque le test a été effectué, Internet était hors ligne (ou Apple en panne), vous ne le savez pas lorsque vous effectuez l'appel Internet sera hors ligne. Vous pourriez penser que c'est une question de millisecondes après le retour de l'appel d'accessibilité, ou que vous avez récupéré la valeur stockée, mais c'est en fait non déterministe. Le système d'exploitation peut avoir planifié un nombre arbitraire de threads avant qu'accessibilité ne renvoie ses valeurs lors de sa fermeture ou ne mette à jour aucun type global que vous stockez.
Et l'accessibilité a toujours eu des bogues dans son propre code.
Cela ne veut pas dire que vous ne devriez pas utiliser le logiciel NetworkReachabilityManager d’alamofire pour modifier votre interface utilisateur, l’écouter et mettre à jour tous ses composants.
Mais si vous avez des raisons d'appeler une API, le test d'accessibilité est redondant au niveau de cette couche, ou peut entraîner des bogues subtils.