即使在触发时,for 循环也不会将 JSON 元素添加到数组中

For loop not adding JSON elements into array even when triggering

假设我有以下 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"))
        }

我的 arrayFromJson 是用

制作的
@State var arrayFromJson: Array<FileCell> = []

我的 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("")
            }
        }
    }
}

并在我的视图中显示为导航 link 和

List {
                ForEach(arrayFromJson){result in

                    NavigationLink(destination: destinationDeterminer(fileName: result.name, fileType: result.fileType)){
                                result }    
                }
        }

如果我只是制作一个数组并手动放入我的 FileCells,应用程序工作正常(事实上,这就是我在调试预览中所做的)。在此示例中,我应该创建 4 个单元格,但我只收到一个单元格(团队)。

编辑:按要求添加附加信息

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 使用此代码从 String 处理

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 是使用这两种方法生成的(一个将 URL 作为字符串检索,另一个处理 JSON 以供使用)

编辑:我做了额外的实验以提供更多信息

添加行时

print(subJson["name"].string ?? "nil")

JSON 中每本词典的 "name" 已打印。但是,数组中的唯一项仍然是 "teams"

尝试使用下面的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()
                }
            }
        }
    }
}