所以假设我有以下JSON:
[
{
"state": "ready",
"type": "folder",
"id": "11f54570-9ea5-11e9-a4b3-717499928918",
"name": "applications",
"public": true,
"update_date": "2019-07-04T21:45:41.959Z"
},
{
"state": "ready",
"type": "folder",
"id": "4128b600-976c-11e9-8289-717499928918",
"name": "home",
"public": true,
"update_date": "2019-06-25T17:11:21.696Z"
},
{
"state": "ready",
"type": "folder",
"id": "11f67df0-9ea5-11e9-a4b3-717499928918",
"name": "resources",
"public": true,
"update_date": "2019-07-04T21:45:41.967Z"
},
{
"state": "ready",
"type": "folder",
"id": "11f2d470-9ea5-11e9-a4b3-717499928918",
"name": "teams",
"public": true,
"update_date": "2019-07-04T21:45:41.944Z"
}
]
我正在尝试创建一个列表,其中包含此 JSON 中每个项目的单元格。我的直觉是创建一个可以显示在列表中的单元格数组。我这样做的方法是使用 For 循环遍历其中的每一个并根据它们的数据初始化一个单元格。
但是,如果传递了我在此处显示的 JSON,则添加到数组中的唯一单元格是最后一个。
我正在使用 SwiftyJson 来处理我的 Json 数据。
我的 for 循环如下:
for (key, subJson) in testJson {
arrayFromJson.append(FileCell(name: subJson["name"].string ?? "nil", fileType: subJson["type"].string ?? "nil", fileDesc: subJson["id"].string ?? "nil"))
}
我的数组FromJson是用
@State var arrayFromJson: Array<FileCell> = []
我的文件单元由以下部分定义:
struct FileCell: Identifiable,View {
var name: String
var fileType: String
var fileDesc: String
var id = UUID()
var body: some View{
var FileImage: String
var fileName = ("(name).(fileType.lowercased())")
var isFolder = false
let ImageType = ["JPEG","JPG","PNG","GIF","BMP"]
let TextType = ["TXT","TEXT","DOC","XML","RTEXT"]
if(fileType.uppercased() == "FOLDER"){
isFolder = true
}
if(isFolder){
FileImage = "folder.fill"
fileName = name
}else if ImageType.contains(fileType.uppercased()) {
FileImage = "photo.fill"
}
else if TextType.contains(fileType.uppercased()) {
FileImage = "doc.text.fill"
} else {
FileImage = "xmark.octagon.fill"
}
return
HStack{
VStack(alignment: .center) {
Image(systemName: FileImage).font(.largeTitle).frame(width: 50)
}
Divider()
VStack(alignment: .leading, spacing: 5.0) {
Text(fileName)
.font(.title)
.multilineTextAlignment(.leading)
Text(fileDesc)
.font(.caption)
.multilineTextAlignment(.center)
}
VStack(alignment: .leading) {
Text("")
}
}
}
}
并在"我的视图"中显示为导航链接
List {
ForEach(arrayFromJson){result in
NavigationLink(destination: destinationDeterminer(fileName: result.name, fileType: result.fileType)){
result }
}
}
如果我只是制作一个数组并手动放入我的 FileCells,该应用程序可以正常工作(事实上,这就是我在调试预览中所做的(。在此示例中,我应该创建 4 个单元格,但我只收到一个单元格(Teams(。
编辑:根据请求添加其他信息
使用此代码从网站检索 JSON
func URLRetrieve(URLtoFetch: String) -> String {
var Value = "No URL"
if(URLtoFetch != ""){
if let url = URL(string: URLtoFetch) {
do {
let contents = try String(contentsOf: url)
//print(contents)
Value = contents
} catch {
print("Failed to load content from URL")
Value = error.localizedDescription
}
}
}
return Value
}
JSON使用此代码从字符串处理
func processJSONFromString(jsonString: String) -> JSON {
var json: JSON = -1
if let dataFromString = jsonString.data(using: .utf8, allowLossyConversion: false) {
do {
json = try JSON(data: dataFromString)
} catch {
print("Failed to Convert Json")
}
}
return json
}
testJson 是在 tandom 中使用这两种方法生成的(一种将 URL 作为字符串检索,另一种处理 JSON 以供使用(
编辑:我做了额外的到期以提供更多信息
添加行时
print(subJson["name"].string ?? "nil")
打印了 JSON 中每个字典的"名称"。但是,数组中唯一的项目仍然是"团队">
尝试使用以下 json 解析逻辑,也许效果更好。可悲的是,我知道的还不够多,也没有看到足够的知识来了解您遇到的具体问题。
import SwiftUI
import os
let data = """
[
{
"state": "ready",
"type": "folder",
"id": "11f54570-9ea5-11e9-a4b3-717499928918",
"name": "applications",
"public": true,
"update_date": "2019-07-04T21:45:41.959Z"
},
{
"state": "ready",
"type": "folder",
"id": "4128b600-976c-11e9-8289-717499928918",
"name": "home",
"public": true,
"update_date": "2019-06-25T17:11:21.696Z"
},
{
"state": "ready",
"type": "folder",
"id": "11f67df0-9ea5-11e9-a4b3-717499928918",
"name": "resources",
"public": true,
"update_date": "2019-07-04T21:45:41.967Z"
},
{
"state": "ready",
"type": "folder",
"id": "11f2d470-9ea5-11e9-a4b3-717499928918",
"name": "teams",
"public": true,
"update_date": "2019-07-04T21:45:41.944Z"
}
]
"""
// MARK: - Folder
struct Folder: Codable, Identifiable {
let state, type, id, name: String
let folderPublic: Bool
let updateDate: String
enum CodingKeys: String, CodingKey {
case state, type, id, name
case folderPublic = "public"
case updateDate = "update_date"
}
}
typealias Folders = [Folder]
struct FileCell: Identifiable,View {
init(file: Folder) {
self.name = file.name
self.fileType = file.type
self.fileDesc = file.id
}
var name: String
var fileType: String
var fileDesc: String
var id = UUID()
var body: some View{
var FileImage: String
var fileName = ("(name).(fileType.lowercased())")
var isFolder = false
let ImageType = ["JPEG","JPG","PNG","GIF","BMP"]
let TextType = ["TXT","TEXT","DOC","XML","RTEXT"]
if(fileType.uppercased() == "FOLDER"){
isFolder = true
}
if(isFolder){
FileImage = "folder.fill"
fileName = name
}else if ImageType.contains(fileType.uppercased()) {
FileImage = "photo.fill"
}
else if TextType.contains(fileType.uppercased()) {
FileImage = "doc.text.fill"
} else {
FileImage = "xmark.octagon.fill"
}
return
HStack{
VStack(alignment: .center) {
Image(systemName: FileImage).font(.largeTitle).frame(width: 50)
}
Divider()
VStack(alignment: .leading, spacing: 5.0) {
Text(fileName)
.font(.title)
.multilineTextAlignment(.leading)
Text(fileDesc)
.font(.caption)
.multilineTextAlignment(.center)
}
VStack(alignment: .leading) {
Text("")
}
}
}
}
struct FilesFromJSONView: View {
@State var folders: [Folder] = []
func parse() {
let folders = try! JSONDecoder().decode(Folders.self, from: data.data(using: .utf8)!)
DispatchQueue.main.async {
self.folders = folders
}
os_log("Parse folders: count = %d", folders.count)
}
var body: some View {
NavigationView{
VStack{
Text("Folders")
List {
ForEach(folders){ (result: Folder) in
NavigationLink(destination: Text(result.id)){
FileCell(file: result) }
}
}.onAppear{
self.parse()
}
}
}
}
}