UUID in Swift3, but “version 1” style UUID

五迷三道 提交于 2019-12-23 20:52:38

问题


This question is about Swift.

It's very easy to generate a rfc UUID in Swift getting a Swift String as at this stage Apple have made a Swift method for it...

func sfUUID()->String
    {
    return UUID().uuidString.lowercased()
    }

I need an old-style "version 1" UUID, when using Swift

(Example: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_.28date-time_and_MAC_address.29)

Is there a way to do this in Swift3? ( >9 only)

In Swift, how to get a Version 1 UUID. So, there might be some option I don't know about on the UUID() call, or there's the difficulty of calling a C call and getting the result safely as a String.


回答1:


Callam's link is the actual answer. Swift can (and in this case must) call C, so the name of the C function is all you really need.

But the "Swift" question here is just how to call a C function from Swift, which is a general skill that's more important than this particular question (and isn't really well explained in the current documentation). So it's worth studying how the following works, and not taking it as just the answer to "how do you generate a v1 UUID in Swift."

var uuid: uuid_t = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
withUnsafeMutablePointer(to: &uuid) {
    $0.withMemoryRebound(to: UInt8.self, capacity: 16) {
        uuid_generate_time($0)
    }
}

let finalUUID = UUID(uuid: uuid)



回答2:


Here's the Swift code I came up with to get to the C call.

It seems pretty clean, and works well.

func generateVersionOneAkaTimeBasedUUID() -> String {

    // figure out the sizes

    let uuidSize = MemoryLayout<uuid_t>.size
    let uuidStringSize = MemoryLayout<uuid_string_t>.size

    // get some ram

    let uuidPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: uuidSize)
    let uuidStringPointer = UnsafeMutablePointer<Int8>.allocate(capacity: uuidStringSize)

    // do the work in C

    uuid_generate_time(uuidPointer)
    uuid_unparse(uuidPointer, uuidStringPointer)

    // make a Swift string while we still have the C stuff

    let uuidString = NSString(utf8String: uuidStringPointer) as? String

    // avoid leaks

    uuidPointer.deallocate(capacity: uuidSize)
    uuidStringPointer.deallocate(capacity: uuidStringSize)

    assert(uuidString != nil, "uuid (V1 style) failed")
    return uuidString ?? ""
}

example outputs

e8d1eb6e-c65f-11e6-bb89-a0999b112ea2
e8d1ed1c-c65f-11e6-bb89-a0999b112ea2
e8d1ed4e-c65f-11e6-bb89-a0999b112ea2

a different physical device

c83fdf22-c660-11e6-aca6-11ad80a9c011
c83fe6e8-c660-11e6-aca6-11ad80a9c011
c83fe904-c660-11e6-aca6-11ad80a9c011


来源:https://stackoverflow.com/questions/41232049/uuid-in-swift3-but-version-1-style-uuid

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!