I need to generate a timestamped object id of BSON format in Swift. The ObjectID is for Mongo DB. How can this be accomplished?
One naive solution would look like this:
func objectId() -> String {
let time = String(Int(Date().timeIntervalSince1970), radix: 16, uppercase: false)
let machine = String(Int.random(in: 100000 ..< 999999))
let pid = String(Int.random(in: 1000 ..< 9999))
let counter = String(Int.random(in: 100000 ..< 999999))
return time + machine + pid + counter
}
The MongoDB docs specifies the following about the ObjectID
The above will satisfy that requirement. However it will only generate random number characters for parts other than the timestamp. A perfect solution would use apis such as NSProcessInfo
and NSUUID
for machine and pid. It would also have to keep track of a counter.
From the MongoDB documentation, an ObjectId is generated using:
You can use this class, which implements the above.
class ObjectId {
private init() {}
static let shared = ObjectId()
private var counter = Int.random(in: 0...0xffffff)
private func incrementCounter() {
if (counter >= 0xffffff) {
counter = 0
} else {
counter += 1
}
}
func generate() -> String {
let time = ~(~Int(NSDate().timeIntervalSince1970))
let random = Int.random(in: 0...0xffffffffff)
let i = counter
incrementCounter()
var byteArray = Array<UInt8>.init(repeating: 0, count: 12)
byteArray[0] = UInt8((time >> 24) & 0xff)
byteArray[1] = UInt8((time >> 16) & 0xff)
byteArray[2] = UInt8((time >> 8) & 0xff)
byteArray[3] = UInt8(time & 0xff)
byteArray[4] = UInt8((random >> 32) & 0xff)
byteArray[5] = UInt8((random >> 24) & 0xff)
byteArray[6] = UInt8((random >> 16) & 0xff)
byteArray[7] = UInt8((random >> 8) & 0xff)
byteArray[8] = UInt8(random & 0xff)
byteArray[9] = UInt8((i >> 16) & 0xff)
byteArray[10] = UInt8((i >> 8) & 0xff)
byteArray[11] = UInt8(i & 0xff)
let id = byteArray
.map({ String($0, radix: 16, uppercase: false)
.padding(toLength: 2, withPad: "0", startingAt: 0) })
.joined()
return id
}
}
The following code will generate a new ObjectId string:
ObjectId.shared.generate()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With