英文:
Parsing JSON into a correct struct format
问题
I will provide translations for the non-code parts of your text:
"Being pretty new to swiftUI development and don't understanding much at the moment I am sorry if this question have already been answered but I couldn't find (or at least understand) anything to solve my problem. To practice, I am trying to create a first app, a flag quizz. While probably being very easy to do, I am having a hard time trying to answer these two questions:
-
What would be the best solution to store the flag images? Would it be in the asset folder, trying to retrieve them from an API, or storing them in a free backend service like Firebase if I need to create more functionalities for the app?
-
I went for the API solution on my side, but I am struggling to get it properly done. I'd like to have an array of "Flag" structs allowing me to randomly pick a "Flag" to be displayed in the view with its associated "shortName" (to retrieve the correct flag from the URL) and "Name." Here is what I have so far:
The JSON file provided by the website is following this format:
With the dictionary created, I'd like to assign the CodingKey to "shortName" and the value of the CodingKey to "name" in order for the link to be correctly initialized once I request a random question from the view.
I'm pretty sure this is definitely not the best way to do it, but as a true beginner, working a little bit with a JSON file can help me a lot.
Many thanks for any help you can provide!"
Please let me know if you need any further assistance.
英文:
Being pretty new to swiftUI development and don't understanding much at the moment I am sorry if this question have already been answered but I couldn't find (or at least understand) anything to solve my problem. To practice, I am trying to create a first app, a flag quizz. While probably being very easy to do, I am having a hard time trying to answer these two questions :
-
What would be the best solution to store the flag images ? Would in it be in the asset folder, trying to retrieve them from an API or storing them in a free backend service as Firebase if I need to create more functionalities to the app ?
-
I went for the API solution on my side but I am struggling to get it properly done. I'd like to have an array of "Flag" structs allowing me to randomly pick a "Flag" to be displayed in the view with its associated "shortName" (to retrieve the correct flag from the URL) and "Name". Here is what I have so far :
import Foundation
let decoder = JSONDecoder()
struct Flag: Codable, Identifiable {
var flagLink: String
var flagDetails: FlagDetails
var id = UUID()
init(flagLink: String, flagDetails: FlagDetails) {
self.flagDetails = flagDetails
self.flagLink = "https://flagcdn.com/w320/\(flagDetails.shortName).png"
}
}
struct FlagDetails: Codable {
var shortName: String
var name: String
}
func getJSON(){
guard let urlJSON = URL(string: "https://flagcdn.com/fr/codes.json") else {
print("Invalid URL")
return
}
URLSession.shared.dataTask(with: urlJSON) { (data, response, error) -> Void in
if error == nil && data != nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
print()
} catch {
print("Invalid data: \(error)")
}
}
}.resume()
}
The JSON file provided by the website is following this format :
{
"ad": "Andorra",
"af": "Afghanistan",
"ag": "Antigua-et-Barbuda",
"ai": "Anguilla"
}
With the dictionary created, I'd like to assign the CodingKey to "shortName" and the value of the CodingKey to "name" in order for the link to be correctly initialized once I request a random question from the view.
I'm pretty sure this is definitely not the best way to do it but as a true beginner, working a little bit with JSON file can help me a lot.
Many thanks for any help you can provide !
答案1
得分: -1
-
我会使用一个框架来下载图片,比如Kingfisher或ImageLoaderSwift。
-
至于回答你的第二个问题:
你可以循环遍历字典,使用 for KEY in DICTIONARY
,然后将值添加到一个数组 (countryFlags
) 中。
只有在你能直接将JSON字符串转换为结构体时才需要Codable,但在这种情况下是不行的,因为你需要一个数组而不是一个字典。
请注意,我不在Mac上,所以无法测试这段代码。
struct Flag {
//.../
// 简化的构造函数
init(shortName: String, name: String) {
self.flagDetails = FlagDetail(shortName: shortName, name: name)
self.flagLink = "https://flagcdn.com/w320/\(shortName).png"
}
}
struct FlagDetails {
//.../
}
var countryFlags = [Flag]()
func getJSON(){
guard let urlJSON = URL(string: "https://flagcdn.com/fr/codes.json") else {
print("无效的URL")
return
}
URLSession.shared.dataTask(with: urlJSON) { (data, response, error) -> Void in
if error == nil && data != nil {
do {
// 将 [String: Any] 更改为 [String: String]
let countryDictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: String]
// 新代码
for (shortName, name) in countryDictionary {
countryFlags.append(Flag(shortName: shortName, name: name))
}
print(countryFlags)
} catch {
print("无效的数据: \(error)")
}
}
}.resume()
}
英文:
-
I would use a framework to download the images, like Kingfisher or ImageLoaderSwift.
-
As for answering your second question:
You can loop through the dictionary, using for KEY in DICTIONARY
, and then add values to an array (countryFlags
).
You only need Codable if you can directly convert a json string to a struct, which you can't in this case, because you need an array and not a dictionary.
Mind you, I'm not on a Mac, so I can't test the code.
struct Flag {
/.../
// Simplified constructor for you
init(shortName: String, name: String) {
self.flagDetails = FlagDetail(shortName: shortName, name: name)
self.flagLink = "https://flagcdn.com/w320/\(shortName).png"
}
}
struct FlagDetails {
/.../
}
var countryFlags = [Flag]()
func getJSON(){
guard let urlJSON = URL(string: "https://flagcdn.com/fr/codes.json") else {
print("Invalid URL")
return
}
URLSession.shared.dataTask(with: urlJSON) { (data, response, error) -> Void in
if error == nil && data != nil {
do {
// Changed [String: Any] to [String: String]
let countryDictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: String]
// NEW CODE
for (shortName, name) in countryDictionary {
countryFlags.append( Flag(shortName: shortName, name: name) )
}
print(countryFlags)
} catch {
print("Invalid data: \(error)")
}
}
}.resume()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论