2012-11-07 10 views
12

Non riesco a trovare alcun modo ufficiale per estrarre una stringa UUID da un CBUUID. Questi UUID possono essere lunghi 2 o 16 byte.Come trasformare CBUUID nella stringa

L'obiettivo è archiviare i CBUUID in un file da qualche parte come una stringa e quindi resuscitare con [CBUUID UUIDWithString:] ecc. Ecco cosa ho finora.

// returns a simple 4 byte string for 16bit uuids, 128 bit uuids are in standard 8-4-4-4-12 format 
// the resulting string can be passed into [CBUUID UUIDWithString:] 
+(NSString*)CBUUIDToString:(CBUUID*)cbuuid; 
{ 
    NSData* data = cbuuid.data; 
    if ([data length] == 2) 
    { 
     const unsigned char *tokenBytes = [data bytes]; 
     return [NSString stringWithFormat:@"%02x%02x", tokenBytes[0], tokenBytes[1]]; 
    } 
    else if ([data length] == 16) 
    { 
     NSUUID* nsuuid = [[NSUUID alloc] initWithUUIDBytes:[data bytes]]; 
     return [nsuuid UUIDString]; 
    } 

    return [cbuuid description]; // an error? 
} 
+0

Apple ha reso obsolete tutte queste risposte con iOS 7.1. Vedi la mia risposta qui sotto. – Andrew

risposta

32

ho truccato la categoria di fare questo per CBUUID:

@interface CBUUID (StringExtraction) 

- (NSString *)representativeString; 

@end 

@implementation CBUUID (StringExtraction) 

- (NSString *)representativeString; 
{ 
    NSData *data = [self data]; 

    NSUInteger bytesToConvert = [data length]; 
    const unsigned char *uuidBytes = [data bytes]; 
    NSMutableString *outputString = [NSMutableString stringWithCapacity:16]; 

    for (NSUInteger currentByteIndex = 0; currentByteIndex < bytesToConvert; currentByteIndex++) 
    { 
     switch (currentByteIndex) 
     { 
      case 3: 
      case 5: 
      case 7: 
      case 9:[outputString appendFormat:@"%02x-", uuidBytes[currentByteIndex]]; break; 
      default:[outputString appendFormat:@"%02x", uuidBytes[currentByteIndex]]; 
     } 

    } 

    return outputString; 
} 

@end 

Per questo ingresso:

NSLog(@"UUID string: %@", [[CBUUID UUIDWithString:@"0bd51666-e7cb-469b-8e4d-2742f1ba77cc"] representativeString]); 
NSLog(@"UUID string2: %@", [[CBUUID UUIDWithString:@"1800"] representativeString]); 

produce il seguente output:

UUID string: 0bd51666-e7cb-469b-8e4d-2742f1ba77cc 
UUID string2: 1800 

e conserva l'hyph appropriato enation per gli UUID a 16 byte, pur supportando i semplici UUID a 2 byte.

+0

Mi è piaciuto. È un po 'più complicato, ma gestisce altre lunghezze. Ma anche il CBUUID è documentato per essere 16 o 128 bit. –

+0

dannazione questo è il capo. grazie ancora! – Makleesh

+0

Perfetto! L'ho appena copiato e incollato appena prima dell'interfaccia @ nel mio file .m e viola! –

4

io so che è stato sette mesi da quando è stato chiesto e ha risposto, ma ... CBUUID è “a ponte numero verde” per CFUUID e il modo più semplice per convertire è

//CBUUID* uuid = descr.UUID; 
NSString* str = CFUUIDCreateString(nil, uuid); 
+1

Funziona con CBUUID lunghi due byte? Non vedo come, dato che sono solo delle strutture. Non sono a pedaggio gratuito. I CFUUID sono semplici structs, mentre CBUUID è un NSObject. C'è un'enorme differenza tra loro. –

+0

Sono contento che tu l'abbia capito da solo. Per il resto di noi funziona. – bioffe

+0

Qualcuno può indicare dove questo è documentato? Né le intestazioni CBUUID né la tabella Toll Free Bridging nella guida Cocoa Fundamentals documentano questo? –

-3

Il che mi segue ha funzionato senza ogni errore:

NSString *str = [[NSString alloc] initWithFormat:@"%@", CFUUIDCreateString(nil, peripheral.UUID) ]; 
+0

Funziona perché gli UUID periferici NON sono CBUUID. Un CBUUID non è un CFUUID. Scoppierà quando consegnato un CBUUID. –

+0

Si prega di verificare con la risposta di bioffe. – Whoami

7

a tutti quelli dicendo che CBUUID è colmato con CFUUIDRef numero verde, non lo è.

CBUUID * foo = [CBUUID UUIDWithString:CBUUIDCharacteristicExtendedPropertiesString]; 
CFStringRef fooBar = CFUUIDCreateString(NULL, (__bridge CFUUIDRef)foo); 
if (![CBUUIDCharacteristicExtendedPropertiesString isEqualToString:(__bridge NSString *)fooBar]) 
    NSLog(@"fubar!"); 

Non è schiantarsi, ma che stai ricevendo spazzatura fuori. Probabilmente identifica in modo univoco la spazzatura, ma non può essere tondo.

PS: questo non ha funzionato come commento perché i commenti di SO stranamente non consentono la formattazione del codice.

+2

non so perché questo è stato downvotato. Mark stai usando una soluzione nello stile della categoria di Brad? – NSTJ

7

iOS 7.1 (beta rilasciata ieri, 11/18/13) ha introdotto la seguente proprietà su CBUUID:

@property(nonatomic, readonly) NSString *UUIDString

The UUID represented as a string. (read-only)

Da CBUUID Class Reference.

E 'anche interessante notare che per il confronto di una stringa UUID con una CBUUID, questo funziona:

if ([cbuuidInQuestion isEqual:[CBUUID UUIDWithString:@"1234-5678-9012-1234"]]) { 
    // isEqual tests for "the same UUID" 
    // == tests for "the same CBUUID object" 
} 
+0

Qualcuno sa se il metodo UUIDString è un metodo non documentato in 7.0? – Tobias

+1

@Tobias non lo è. – Andrew

+0

La proprietà UUIDString è stata eliminata dal documento! –

-1

di Brad answer fa il suo lavoro, ma la soluzione potrebbe essere più semplice (anche se probabilmente non più efficiente) utilizzando NSUUID classe :

// CBUUID+ToString.h 

#import <CoreBluetooth/CoreBluetooth.h> 

@interface CBUUID (ToString) 

- (NSString *)toString; 

@end 

// CBUUID+ToString.m 

#import "CBUUID+ToString.h" 

@implementation CBUUID (ToString) 

- (NSString *)toString { 
    if ([self respondsToSelector:@selector(UUIDString)]) { 
     return [self UUIDString]; // Available since iOS 7.1 
    } else { 
     return [[[NSUUID alloc] initWithUUIDBytes:[[self data] bytes]] UUIDString]; // iOS 6.0+ 
    } 
} 

@end 
+0

OSX 10.10 (Yosemite) ha anche 'UUIDString' disponibile – tofi9

+0

' initWithUUIDBytes: 'si aspetta otto byte di dati. Nel caso di un CBUUID a 16 bit questo è un comportamento indefinito. –

+0

"Le istanze della classe CBUUID rappresentano gli identificatori universalmente univoci a 128 bit", pertanto il codice è valido. – werediver

1

Ecco una rapida estensione della risposta di Brad Larson:

import CoreBluetooth 

extension CBUUID { 

    func representativeString() -> String { 
     let data = self.data 

     let bytesToConvert = data.length 
     let uuidBytes = UnsafePointer<CUnsignedChar>(data.bytes) 
     var outputString = String() 

     for currentByteIndex in 0..<bytesToConvert { 
      switch currentByteIndex { 
      case 3,5,7,9: 
       outputString += String(format: "%02x-",uuidBytes[currentByteIndex]) 
      default: 
       outputString += String(format: "%02x",uuidBytes[currentByteIndex]) 
      } 
     } 

     return outputString 
    } 
} 

Da iOS 7.1 UUIDString la proprietà è presente ma per iOS7 specifico, l'estensione sopra è una buona opzione.

+2

errore su UnsafePointer in swift 3.0 –