decode JSON UUID correctly

Hello,


This is a beginner question but it has me stumped. I have a JSON file in the bundle that includes valid UUIDs generated from within Xcode in the format "D9BB6CD0-FBB9-49B9-9076-07D49E1707B2". I want to store these in a UUID variable within a struct.


struct model: Codable {
    var id: UUID
    var name: String
    …
}


I use a standard JSONDecoder() call to import the models.


let importedModels = Bundle.main.decode([model].self, from: "models.json")


All of the other JSON data imports correctly. In fact it's been working so well it took me a while to notice that the UUIDs were not being populated. I just get a nil value for variable id.


I believe what's happening is that the decoder isn't initialising the UUID from the string properly and it's quietly failing (on UUID data only). But I don't understand why because in the definition for public struct UUID in Foundation it says,


    /// Create a UUID from a string such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F".
    /// 
    /// Returns nil for invalid strings.
    public init?(uuidString string: String)


So if the string is valid is should work and I am using valid strings.


E621E1F8-C36C-495A-93FC-0C247A3E6E5F     // Foundation documentation
D9BB6CD0-FBB9-49B9-9076-07D49E1707B2     // from models.json


Any help greatly appreciated.

Answered by OOPer in 401806022

I use a standard JSONDecoder() call to import the models.

I cannot find any standard `JSONDecoder()` calls, and your code causes error on my Xcode:

Value of type 'Bundle' has no member 'decode'


I guess your `decode` may be wrong or your `models.json` may be wrong.

Please show your code and data.


As far as I tried with the following code and data, `JSONDecoder()` works fine with UUID:

struct Model: Codable {
    var id: UUID
    var name: String
    //…
}

let modelsUrl = Bundle.main.url(forResource: "models", withExtension: "json")!
let modelsData = try! Data(contentsOf: modelsUrl)
let importedModels = try! JSONDecoder().decode([Model].self, from: modelsData)

print(importedModels)

models.json:

[
    {"id":"D9BB6CD0-FBB9-49B9-9076-07D49E1707B2","name":"name"}
]
Accepted Answer

I use a standard JSONDecoder() call to import the models.

I cannot find any standard `JSONDecoder()` calls, and your code causes error on my Xcode:

Value of type 'Bundle' has no member 'decode'


I guess your `decode` may be wrong or your `models.json` may be wrong.

Please show your code and data.


As far as I tried with the following code and data, `JSONDecoder()` works fine with UUID:

struct Model: Codable {
    var id: UUID
    var name: String
    //…
}

let modelsUrl = Bundle.main.url(forResource: "models", withExtension: "json")!
let modelsData = try! Data(contentsOf: modelsUrl)
let importedModels = try! JSONDecoder().decode([Model].self, from: modelsData)

print(importedModels)

models.json:

[
    {"id":"D9BB6CD0-FBB9-49B9-9076-07D49E1707B2","name":"name"}
]

Thanks OOper - I think my knowledge gap was with respect to debugging not UUID. I put together a test application to look into this more closely (see below) and even if you have a valid value in var id: UUID, in the debugger it will show Value (None). Which is kind of weird - surely it should show the string value of the UUID variable?


But the simple summary was that my code was fine and your help was appreciated. 🙂



Thanks for reporting, which has reminded me of the fact that the current Xcode keeps the old known bug.

What is astonishing for me is that this bug has been existing at least since Xcode 11.1 (may be older...).


Please file a bug report. It may be classified as duplicate, but I want to believe the number affects (said by an Apple engineer).

I'm encountering the same problem.

Please start a new thread with detailed description of your problem.


You may reference this thread if you want.

decode JSON UUID correctly
 
 
Q