2017-01-11 3 views
2

У меня есть следующий код, написанный в Objective C, который я пытаюсь получить в Swift 3. Некоторые из эквивалентов функций не отображаются в Swift 3. Вот код: код в Objective CПолучить данные из UUID в Swift 3

NSUUID *vendorIdentifier = [[UIDevice currentDevice] identifierForVendor]; 
uuid_t uuid; 
[vendorIdentifier getUUIDBytes:uuid]; 
NSData *vendorData = [NSData dataWithBytes:uuid length:16]; 

и мои текущие усилия в Swift 3, который компилируется и работает, но не дает правильный ответ.

let uuid = UIDevice.current.identifierForVendor?.uuidString 
let uuidData = uuid?.data(using: .utf8) 
let uuidBytes = uuidData?.withUnsafeBytes { UnsafePointer<UInt8>($0) } 
let vendorData : NSData = NSData.init(bytes: uuidBytes, length: 16) 
let hashData = NSMutableData() 
hashData.append(vendorData as Data) 
+0

могли бы вы добавить результаты, что вы ожидаете и что вы получите от быстры код? – muescha

+0

Я пытаюсь. Я не делаю многого в Objective C. – Andrew

ответ

4

Свойство uuidUUID является массивом C, импортированным в Swift в качестве кортежа. Используя тот факт, что Swift сохраняет макет памяти импортируемых структур C, вы можете передать указатель на кортеж к Data(bytes:, count:) конструктора:

if let vendorIdentifier = UIDevice.current.identifierForVendor { 
    var uuid = vendorIdentifier.uuid 
    let data = withUnsafePointer(to: &uuid) { 
     Data(bytes: $0, count: MemoryLayout.size(ofValue: uuid)) 
    } 

    // ... 
} 
+0

Разве не лучше делать '& uuid.0'' 'и uuid'? – OOPer

+1

С семантикой включения/выключения Swift, Swift может подготовить регион, который может содержать только один байт и передавать адрес региона, если вы используете '& uuid.0'. В большинстве случаев '& uuid.0' будет работать, но это недостаточно безопасно. – OOPer

+0

@OOPer: Вы правы, спасибо за отзыв! –

3

Вот один из возможных способов. Обратите внимание, что identifierForVendor возвращает UUID в Свифт 3. UUID имеет uuid объект который дает вам uuid_t. uuid_t - это набор из 16 UInt8 значений.

Итак, трюк преобразует кортеж байтов в массив байтов. Тогда тривиально создать Data из массива.

if let vendorIdentifier = UIDevice.current.identifierForVendor { 
    let uuid = vendorIdentifier.uuid // gives a uuid_t 
    let uuidBytes = Mirror(reflecting: uuid).children.map({$0.1 as! UInt8}) // converts the tuple into an array 
    let vendorData = Data(bytes: uuidBytes) 
} 

Если кто-нибудь знает лучший способ преобразовать кортеж UInt8 в массив UInt8, пожалуйста, говорить.

+0

Мне пришлось добавить байты: let vendorData = Data (bytes: uuidBytes) – Andrew

+0

@Andrew В игровой площадке мне не нужно имя параметра 'bytes:'. – rmaddy

Смежные вопросы