[英]Having trouble with print output of object decoded with JSONDecoder
我正在嘗試解碼 swift 中的 JSON 字符串,但在解碼后訪問屬性時遇到一些奇怪的問題。
這是我從本地存儲的 JSON 文件中檢索到的 JSON 文件的內容
[
{
"word": "a",
"usage": [
{
"partOfSpeech": "determiner"
}
]
}
]
這是訪問 JSON 文件屬性的代碼
struct WordDictionary : Codable {
var word: String
var usage: [Usage]
}
struct Usage: Codable {
var partOfSpeech: String
}
if let url = Bundle.main.url(forResource: FILE_NAME, withExtension: "json") {
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let jsonData = try decoder.decode([WordDictionary].self, from: data)
print(jsonData[0].word) //Outputs "a"
print(jsonData[0].usage) //Outputs "[MyApp.AppDelegate.(unknown context at $102a37f00).(unknown context at $102a38038).Usage(partOfSpeech: "determiner")]"
} catch {
print("error:\(error)")
}
}
如您所見,當我嘗試print(jsonData[0].usage)
時,我在獲取“Usage”屬性之前收到了一系列未知數據消息。 當我打印這一行時,我只想看到determiner
,我不確定關於“未知上下文”的序言是什么。
我還在AppDelegate
的didFinishLaunchingWithOptions
function 中運行這段代碼。
我不確定我錯過了什么。 幾天來我一直在嘗試尋找解決方案並嘗試不同的方法,但仍然無法獲得所需的 output,我們將不勝感激。
如果您希望某個類型在將其實例插入字符串時能夠很好地打印,則需要使其符合CustomStringConvertible 。
該協議聲明了一個屬性: description
,當字符串插值遇到符合它的 object 時,它會使用description
返回的字符串。
你需要這樣的東西:
extension Usage: CustomStringConvertible
{
var description: String
{
return "{ \"partOfSpeech\" : \"\(partOfSpeech)\" }"
}
}
如果你想打印一個 JSON 之類的*字符串。
另一種方法是使用 JSONEncoder 重新編碼JSONEncoder
並將數據轉換為String
。 這要重得多,但對於更復雜的物體來說可能是更好的選擇。
* JSON 之類的,因為換行符和制表符之類的東西不會被轉義符替換,字符串中出現的"
和\
也不會被轉義。
tl;博士
您在類型的描述中看到“未知上下文”,因為它是在 function 中定義的。您可以通過將這些類型定義移到 function 之外或實現您自己的CustomStringConvertible
一致性來解決此問題。
這是你在哪里定義你的類型的問題。
考慮:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
struct WordDictionary: Codable {
var word: String
var usage: [Usage]
}
struct Usage: Codable {
var partOfSpeech: String
}
do {
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
let data = try Data(contentsOf: url)
let words = try JSONDecoder().decode([WordDictionary].self, from: data)
print(words[0].usage)
} catch {
print(error)
}
return true
}
...
}
產生:
[MyApp.AppDelegate。($102bac454 的未知上下文)。($102bac58c 的未知上下文)。用法(partOfSpeech:“確定器”)]
也就是說Usage
是在MyApp
的AppDelegate
中的某個未知上下文中定義的。 簡而言之,它不知道如何表示函數內定義的類型的層次結構。
對比一下:
class AppDelegate: UIResponder, UIApplicationDelegate {
struct WordDictionary: Codable {
var word: String
var usage: [Usage]
}
struct Usage: Codable {
var partOfSpeech: String
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
let data = try Data(contentsOf: url)
let words = try JSONDecoder().decode([WordDictionary].self, from: data)
print(words[0].usage)
} catch {
print(error)
}
return true
}
...
}
哪個產生:
[MyApp.AppDelegate.Usage(partOfSpeech: "determiner")]
您還可以添加自己的CustomStringConvertible
一致性:
struct WordDictionary: Codable {
var word: String
var usage: [Usage]
}
struct Usage: Codable {
var partOfSpeech: String
}
extension Usage: CustomStringConvertible {
var description: String { "Usage(partOfSpeech: \"\(partOfSpeech)\")" }
}
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
let data = try Data(contentsOf: url)
let words = try JSONDecoder().decode([WordDictionary].self, from: data)
print(words[0].usage)
} catch {
print(error)
}
return true
}
...
}
哪個產生:
[用法(partOfSpeech:“限定詞”)]
通過CustomStringConvertible
,您可以根據需要制作print
格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.