J'essaye de convertir cet extrait de code en Swift. J'ai du mal à décoller à cause de certaines difficultés.
- (BOOL) connectedToNetwork
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
Le premier et le principal problème que j'ai est de savoir comment définir et travailler avec des structures C. Dans la première ligne ( struct sockaddr_in zeroAddress;
) du code ci-dessus, je pense qu'ils définissent une instance appelée à zeroAddress
partir de la structure sockaddr_in (?), Je suppose. J'ai essayé de déclarer un var
comme ça.
var zeroAddress = sockaddr_in()
Mais j'obtiens l'erreur Argument manquant pour le paramètre 'sin_len' dans l'appel, ce qui est compréhensible car cette structure prend un certain nombre d'arguments. Alors j'ai réessayé.
var zeroAddress = sockaddr_in(sin_len: sizeof(zeroAddress), sin_family: AF_INET, sin_port: nil, sin_addr: nil, sin_zero: nil)
Comme prévu, j'obtiens une autre variable d' erreur utilisée dans sa propre valeur initiale . Je comprends aussi la cause de cette erreur. En C, ils déclarent d'abord l'instance, puis remplissent les paramètres. Ce n'est pas possible dans Swift pour autant que je sache. Je suis donc vraiment perdu à ce stade sur ce qu'il faut faire.
J'ai lu le document officiel d'Apple sur l'interaction avec les API C dans Swift mais il n'a pas d'exemples de travail avec les structures.
Quelqu'un peut-il m'aider ici? J'apprécierais vraiment.
Je vous remercie.
MISE À JOUR: Grâce à Martin, j'ai pu surmonter le problème initial. Mais Swift ne me facilite toujours pas la tâche. Je reçois plusieurs nouvelles erreurs.
func connectedToNetwork() -> 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)
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(UnsafePointer<Void>, UnsafePointer<zeroAddress>) // 'zeroAddress' is not a type
var flags = SCNetworkReachabilityFlags()
let didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, UnsafeMutablePointer<flags>) // 'flags' is not a type
defaultRouteReachability.dealloc(1) // 'SCNetworkReachabilityRef' does not have a member named 'dealloc'
if didRetrieveFlags == false {
return false
}
let isReachable: Bool = flags & kSCNetworkFlagsReachable // Cannot invoke '&' with an argument list of type '(@lvalue UInt32, Int)'
let needsConnection: Bool = flags & kSCNetworkFlagsConnectionRequired // Cannot invoke '&' with an argument list of type '(@lvalue UInt32, Int)'
return (isReachable && !needsConnection) ? true : false
}
EDIT 1: OK, j'ai changé cette ligne en ceci,
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(UnsafePointer<Void>(), &zeroAddress)
La nouvelle erreur que j'obtiens à cette ligne est que «UnsafePointer» n'est pas convertible en «CFAllocator» . Comment passer NULL
à Swift?
J'ai également changé cette ligne et l'erreur a disparu maintenant.
let didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags)
EDIT 2: je suis passé nil
dans cette ligne après avoir vu cette question. Mais cette réponse est en contradiction avec la réponse ici . Il dit qu'il n'y a pas d'équivalent à NULL
Swift.
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress)
Quoi qu'il en soit, j'obtiens une nouvelle erreur disant que «sockaddr_in» n'est pas identique à «sockaddr» à la ligne ci-dessus.