2012-11-07 41 views
12

我找不到任何官方的方式將UUID字符串從CBUUID中取出。這些UUID的長度可以是2或16個字節。如何將CBUUID轉換爲字符串

目標是將CBUUID作爲字符串存儲在某個文件中,然後使用[CBUUID UUIDWithString:]重新生成等等。這是迄今爲止我所擁有的。

// 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

蘋果只是在iOS 7.1中將所有這些答案都廢棄了。請參閱下面的答案。 – Andrew

回答

32

我裝配了以下類別爲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 

對於此輸入:

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

它產生以下輸出:

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

並保留適當的hyph支持16字節的UUID,同時支持簡單的2字節UUID。

+0

喜歡它。它稍微複雜一些,但它確實可以處理其他長度。但是CBUUID也被記錄爲16位或128位。 –

+0

該死的這是老闆。再次感謝! – Makleesh

+0

工作完美!我只是將其複製並粘貼到我的.m文件中的@interface之前,然後中提琴! –

4

我知道這是已有7月起有人問和回答,但是...... CBUUID是「免費橋接」到CFUUID和轉換的最簡單的方法是

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

這是否與兩個字節長的CBUUID一起工作?我不明白,鑑於他們只是結構。他們不是免費橋接。 CFUUID是簡單的結構,而CBUUID是一個NSObject。他們之間有巨大的差異。 –

+0

我很高興你爲自己想出了。對於我們其他人來說,它只是起作用。 – bioffe

+0

任何人都可以指出這是記錄在哪裏? Cocoa Fundamentals指南中的CBUUID標題和免費橋接表都沒有提供此文檔? –

-3

以下逼着我沒有任何錯誤:

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

這是可行的,因爲外圍UUID不是CBUUID。 CBUUID不是CFUUID。交給CBUUID時會爆炸。 –

+0

請檢查bioffe的回覆。 – Whoami

7

對所有那些說CBUUID是免費電話與CFUUIDRef橋,事實並非如此。

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

它不會崩潰,但你會得到垃圾。這可能是唯一識別垃圾的方法,但它不能被循環使用。

PS:這不作爲評論工作,因爲SO評論奇怪地不允許代碼格式。

+2

不確定爲什麼這個人被低估了 - 馬克是否在使用布拉德類別風格的解決方案? – NSTJ

7

的iOS 7.1(測試版昨日公佈,13年11月18日)介紹CBUUID以下屬性:

@property(nonatomic, readonly) NSString *UUIDString

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

CBUUID Class Reference

另外值得一提的是,對於一個UUID字符串以CBUUID相比,這個工程:

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

任何人都知道UUIDString方法在7.0中是否是未公開的方法? – Tobias

+1

@Tobias不是。 – Andrew

+0

UUIDString屬性已從文檔中消失! –

-1

布拉德的answer做的工作,但解決方案可能是簡單的(儘管可能不是更有效)使用NSUUID類:

// 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)也有'UUIDString'可用 – tofi9

+0

'initWithUUIDBytes:'需要八個字節的數據。在16位CBUUID的情況下,這是未定義的行爲。 –

+0

「CBUUID類的實例代表128位通用唯一標識符」,因此代碼是有效的。 – werediver

1

這裏是布拉德·拉爾森的回答迅速擴展:

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 
    } 
} 

來自iOS 7.1 UUIDString屬性是存在,但對於特定的iOS7,以上擴展是很好的選擇。

+2

在swift 3.0中的UnsafePointer上出錯 –