2017-07-24 2 views
0

J'ai rencontré des problèmes lors de la conversion d'un extrait Objective-C en Swift qui utilise NSData et CoreBluetooth. J'ai regardé this question et un couple d'autres traitant NSData dans Swift mais n'ai pas eu de succès.Problème lors de la conversion du code objectif-C NSData en Swift

Objective-C Snippet:

- (CGFloat) minTemperature 
{ 
    CGFloat result = NAN; 
    int16_t value = 0; 

    // characteristic is a CBCharacteristic 
    if (characteristic) { 
     [[characteristic value] getBytes:&value length:sizeof (value)]; 
     result = (CGFloat)value/10.0f; 
    } 
    return result; 
} 

Ce que j'ai jusqu'à présent à Swift (ne fonctionne pas):

func minTemperature() -> CGFloat { 
    let bytes = [UInt8](characteristic?.value) 
    let pointer = UnsafePointer<UInt8>(bytes) 
    let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 } 
    value = Int16(fPointer.pointee) 

    result = CGFloat(value/10) // not correct value 

    return result 
} 

Est-ce que la logique regard ne va pas ici? Merci!

Répondre

0

Une erreur est dans

let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 } 

parce que le pointeur de rebond $0 est uniquement valable à l'intérieur de la fermeture et doit pas passé à l'extérieur. La capacité doit également être 1 pour une valeur unique Int16. Un autre problème est la division entière dans

result = CGFloat(value/10) 

qui tronque le résultat (comme déjà observed by the4kman).

Création d'un tableau [UInt8] à partir des données n'est pas nécessaire, la méthode withUnsafeBytes() de Data peut être utilisé à la place.

Enfin, vous pouvez revenir nil (au lieu de « pas un nombre ») si aucune valeur caractéristique est donnée:

func minTemperature() -> CGFloat? { 
    guard let value = characteristic?.value else { 
     return nil 
    } 
    let i16val = value.withUnsafeBytes { (ptr: UnsafePointer<Int16>) in 
     ptr.pointee 
    } 
    return CGFloat(i16val)/10.0 
} 
0

Vous devez rendre la valeur de retour facultative et vérifier si characteristic est nul au début avec un guard. Vous devez convertir explicitement la valeur à CGFloat, puis diviser par 10.

func minTemperature() -> CGFloat? { 
    guard characteristic != nil else { 
     return nil 
      } 

    let bytes = [UInt8](characteristic!.value) 
    let pointer = UnsafePointer<UInt8>(bytes) 
    let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 } 
    let value = Int16(fPointer.pointee) 

    result = CGFloat(value)/10 

    return result 
} 
+0

aime valeur Casting qui donne l'erreur « ne peut pas invoquer initialiseur pour le type « CGFloat » avec un Liste des arguments de type '(_)' " – Surz

+0

Vérifiez ma réponse mise à jour. – the4kman