Estoy intentando convertir este fragmento de código a Swift. Estoy luchando para despegar debido a algunas dificultades.
- (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;
}
El primer y principal problema que tengo es cómo definir y trabajar con estructuras C. En la primera línea ( struct sockaddr_in zeroAddress;
) del código anterior, creo que están definiendo una instancia llamada zeroAddress
desde la estructura sockaddr_in (?), Supongo. Intenté declarar algo var
así.
var zeroAddress = sockaddr_in()
Pero obtengo el error Faltante argumento para el parámetro 'sin_len' en la llamada, lo cual es comprensible porque esa estructura toma varios argumentos. Así que lo intenté de nuevo.
var zeroAddress = sockaddr_in(sin_len: sizeof(zeroAddress), sin_family: AF_INET, sin_port: nil, sin_addr: nil, sin_zero: nil)
Como esperaba, obtengo otra Variable de error utilizada dentro de su propio valor inicial . También entiendo la causa de ese error. En C, primero declaran la instancia y luego completan los parámetros. No es posible en Swift que yo sepa. Así que estoy realmente perdido en este punto sobre qué hacer.
Leí el documento oficial de Apple sobre la interacción con las API de C en Swift, pero no tiene ejemplos sobre cómo trabajar con estructuras.
¿Alguien puede ayudarme aquí? Realmente lo agradecería.
Gracias.
ACTUALIZACIÓN: Gracias a Martin pude superar el problema inicial. Pero aún así Swift no me lo pone más fácil. Recibo varios errores nuevos.
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
}
EDITAR 1: Bien, cambié esta línea a esto,
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(UnsafePointer<Void>(), &zeroAddress)
El nuevo error que recibo en esta línea es 'UnsafePointer' no se puede convertir a 'CFAllocator' . ¿Cómo pasar NULL
en Swift?
También cambié esta línea y el error desapareció ahora.
let didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags)
EDICIÓN 2: Pasé nil
en esta línea después de ver esta pregunta. Pero esa respuesta contradice la respuesta aquí . Dice que no hay equivalente NULL
en Swift.
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress)
De todos modos , aparece un nuevo error que dice que 'sockaddr_in' no es idéntico a 'sockaddr' en la línea anterior.