即使在触发时,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()
}
}
}
}
}
假设我有以下 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()
}
}
}
}
}