如何同时从两个 JSON 字段中过滤(SwiftUI)
How to filter from two JSON fields at the same time (SwiftUI)
我正在尝试根据系统语言同时过滤来自两个JSON字段的数据:此时,系统语言识别似乎起作用(因为根据系统语言出现不同的元素), 但由于某些原因,我无法找到执行我想做的事情的确切代码...
正如您从代码中看到的那样,我首先尝试过滤特定单词(“意大利语”或“英语”)的“数据”字段,然后是“自动”字段以对各种信息进行分类。 .但结果并不好:有时我在列表中看到重复的相同信息,其他时候我只看到从“数据”字段而不是从“autore”字段过滤的信息...
所以,总而言之,我想获得的结果如下:如果系统语言是意大利语,则所有 JSON 在“数据”字段中包含关键字“意大利语”的数据必须是先过滤,再根据“autore”字段包含的具体关键字进一步过滤;另一方面,如果系统语言不是意大利语(而是任何其他语言),则必须首先过滤“数据”字段中包含关键字“english”的所有 JSON 数据,然后 - 如前一个案例 - 根据“autore”字段中包含的特定关键字进一步过滤。
你有什么建议吗?因为我认为我离确切的代码不是很远……或者可能不是:)
谢谢!
这是 SwiftUI 代码:
import SwiftUI
import URLImage
struct HistoryView: View {
@ObservedObject var dm: DownloadManager
let sysLanguage = NSLocale.current.languageCode
var body: some View {
if sysLanguage == "it" {
List {
ForEach(dm.JSON.filter {
[=11=].data == "italiano"
}) { busso in
ForEach(dm.JSON.filter {
[=11=].autore == "storia"
}) { busso in
NavigationLink(
destination: DetailView(busso: busso)) {
HStack {
URLImage(URL(string: busso.fotoUrl) ?? furl)
.resizable()
.aspectRatio(contentMode: .fit)
Text(busso.titolo)
.font(.headline)
Spacer().layoutPriority(-0.1)
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 50)
}
}
}
}
.navigationTitle(Text("Storia di Busso"))
.navigationBarTitleDisplayMode(.large)
} else {
List {
ForEach(dm.JSON.filter {
[=11=].autore == "storia"
}) { busso in
ForEach(dm.JSON.filter {
[=11=].data == "english"
}) { busso in
NavigationLink(
destination: DetailView(busso: busso)) {
HStack {
URLImage(URL(string: busso.fotoUrl) ?? furl)
.resizable()
.aspectRatio(contentMode: .fit)
Text(busso.titolo)
.font(.headline)
Spacer().layoutPriority(-0.1)
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 50)
}
}
}
}
.navigationTitle(Text("Storia di Busso"))
.navigationBarTitleDisplayMode(.large)
}
}
}
struct HistoryView_Previews: PreviewProvider {
static var previews: some View {
HistoryView(dm: DownloadManager())
}
}
这是 JSON 文件:
[
{
"id": "8",
"titolo": "View",
"autore": "galleria",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-13 22:55:57",
"foto": "foto\/WP_20161110_001.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/WP_20161110_001.jpg"
},
{
"id": "7",
"titolo": "Storia di Busso",
"autore": "storia",
"testo": "Testo di prova",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-10 21:11:03",
"foto": "foto\/1a3e733334ec8948b0328af4e5b7288a.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/1a3e733334ec8948b0328af4e5b7288a.jpg"
},
{
"id": "6",
"titolo": "Test 2",
"autore": "ricette",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:49:56",
"foto": "foto\/test_2.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/test_2.jpg"
},
{
"id": "5",
"titolo": "Test",
"autore": "eventi",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:47:53",
"foto": "foto\/coastal-wash-web.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/coastal-wash-web.jpg"
},
{
"id": "4",
"titolo": "Immagine di prova",
"autore": "luoghi",
"testo": "",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:24:46",
"foto": "foto\/unnamed.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/unnamed.jpg"
},
{
"id": "3",
"titolo": "Panorama",
"autore": "galleria",
"testo": "",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-07 11:21:53",
"foto": "foto\/WP_20161110_001.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/WP_20161110_001.jpg"
},
{
"id": "2",
"titolo": "Comune di Busso",
"autore": "contatti",
"testo": "Indirizzo, telefono, mail, altri dati da inserire",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-01 19:33:56",
"foto": "foto\/DSCN0914.JPG",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/DSCN0914.JPG"
},
{
"id": "1",
"titolo": "Chiesa",
"autore": "commercio",
"testo": "Testo di prova, abbastanza lungo per verificare l'impaginazione e correggere eventuali errori.",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-01 19:32:02",
"foto": "foto\/CAM_0044.JPG",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/CAM_0044.JPG"
}
]
下载管理器代码如下:
import SwiftUI
import Combine
class DownloadManager: ObservableObject {
@Published var JSON: [BussoModel] = []
@Published var searchText: String = "" {
didSet {
self.searchResults = self.JSON.filter { [=13=].titolo.contains(self.searchText) }
}
}
@Published var searchResults: [BussoModel] = []
init() {
let url = URL(string: "https://geniuspointfrezza.altervista.org/index.php?json=1")!
URLSession.shared.dataTask(with: url) {(data, response, error) in
do {
if let bussoData = data {
let decodedData = try JSONDecoder().decode([BussoModel].self, from: bussoData)
DispatchQueue.main.async {
self.JSON = decodedData
}
} else {
print("No data")
}
} catch {
print(error)
}
}.resume()
}
}
根据您的评论,我相信这就是您想要做的(除非我误解了什么)。我从代码中删除了 URL 图片,因此您必须将其添加回来。
几个注意事项:
- 尝试在 DownloadManager 中进行所有过滤和数据管理。我添加了一个过滤器函数,它在数据下载时以及视图初始化时调用。
- 尽量避免将字符串硬编码到您的代码中。我创建了一个将处理“英语”和“意大利语”过滤器的语言枚举。
- 如果您 运行 在代码中复制了整个部分(例如在 post 中您重写了“it”和“else”的视图),那么肯定有更好的方法。
.
import SwiftUI
//import URLImage
struct HistoryView: View {
@ObservedObject var dm: DownloadManager
let title: String
init(dm: DownloadManager, autore: String) {
self.dm = dm
dm.filter(autore: autore)
self.title = "\(autore)".capitalized + " di Busso"
}
var body: some View {
List {
if !dm.searchResults.isEmpty && !dm.isLoading {
ForEach(dm.searchResults) { busso in
NavigationLink(
destination: Text(busso.titolo)) {
HStack {
Text(busso.fotoUrl)
Text(busso.titolo)
.font(.headline)
Spacer(minLength: 0)
}
.frame(maxWidth: .infinity)
.frame(height: 50)
}
}
} else if dm.isLoading {
ProgressView()
} else {
Text("No results.")
}
}
.navigationTitle(title)
}
}
struct HistoryView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
HistoryView(dm: DownloadManager(), autore: "galleria")
}
}
}
import SwiftUI
import Combine
class DownloadManager: ObservableObject {
@Published private(set) var JSON: [BussoModel] = []
@Published private(set) var isLoading: Bool = true
@Published private(set) var searchAutore: String?
@Published private(set) var searchResults: [BussoModel] = []
let language: Language
enum Language: String {
case italian
case english
}
init() {
language = NSLocale.current.languageCode == "it" ? .italian : .english
getData()
}
private func getData() {
let url = URL(string: "https://geniuspointfrezza.altervista.org/index.php?json=1")!
URLSession.shared.dataTask(with: url) {(data, response, error) in
do {
if let bussoData = data {
let decodedData = try JSONDecoder().decode([BussoModel].self, from: bussoData)
DispatchQueue.main.async {
self.JSON = decodedData
self.isLoading = false
self.filter(autore: self.searchAutore)
}
} else {
print("No data")
self.isLoading = false
}
} catch {
print(error)
self.isLoading = false
}
}.resume()
}
func filter(autore: String?) {
searchAutore = autore
searchResults = JSON.filter({ (bussoModel) -> Bool in
return bussoModel.data == language.rawValue && (bussoModel.autore == searchAutore)
})
}
}
struct BussoModel: Codable, Identifiable {
let id: String
let titolo: String
let autore: String
let testo: String
let data: String
let extra1: String
let extra2: String
let creazione: String
let foto: String
let fotoUrl: String
}
我正在尝试根据系统语言同时过滤来自两个JSON字段的数据:此时,系统语言识别似乎起作用(因为根据系统语言出现不同的元素), 但由于某些原因,我无法找到执行我想做的事情的确切代码...
正如您从代码中看到的那样,我首先尝试过滤特定单词(“意大利语”或“英语”)的“数据”字段,然后是“自动”字段以对各种信息进行分类。 .但结果并不好:有时我在列表中看到重复的相同信息,其他时候我只看到从“数据”字段而不是从“autore”字段过滤的信息...
所以,总而言之,我想获得的结果如下:如果系统语言是意大利语,则所有 JSON 在“数据”字段中包含关键字“意大利语”的数据必须是先过滤,再根据“autore”字段包含的具体关键字进一步过滤;另一方面,如果系统语言不是意大利语(而是任何其他语言),则必须首先过滤“数据”字段中包含关键字“english”的所有 JSON 数据,然后 - 如前一个案例 - 根据“autore”字段中包含的特定关键字进一步过滤。
你有什么建议吗?因为我认为我离确切的代码不是很远……或者可能不是:) 谢谢!
这是 SwiftUI 代码:
import SwiftUI
import URLImage
struct HistoryView: View {
@ObservedObject var dm: DownloadManager
let sysLanguage = NSLocale.current.languageCode
var body: some View {
if sysLanguage == "it" {
List {
ForEach(dm.JSON.filter {
[=11=].data == "italiano"
}) { busso in
ForEach(dm.JSON.filter {
[=11=].autore == "storia"
}) { busso in
NavigationLink(
destination: DetailView(busso: busso)) {
HStack {
URLImage(URL(string: busso.fotoUrl) ?? furl)
.resizable()
.aspectRatio(contentMode: .fit)
Text(busso.titolo)
.font(.headline)
Spacer().layoutPriority(-0.1)
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 50)
}
}
}
}
.navigationTitle(Text("Storia di Busso"))
.navigationBarTitleDisplayMode(.large)
} else {
List {
ForEach(dm.JSON.filter {
[=11=].autore == "storia"
}) { busso in
ForEach(dm.JSON.filter {
[=11=].data == "english"
}) { busso in
NavigationLink(
destination: DetailView(busso: busso)) {
HStack {
URLImage(URL(string: busso.fotoUrl) ?? furl)
.resizable()
.aspectRatio(contentMode: .fit)
Text(busso.titolo)
.font(.headline)
Spacer().layoutPriority(-0.1)
}
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 50)
}
}
}
}
.navigationTitle(Text("Storia di Busso"))
.navigationBarTitleDisplayMode(.large)
}
}
}
struct HistoryView_Previews: PreviewProvider {
static var previews: some View {
HistoryView(dm: DownloadManager())
}
}
这是 JSON 文件:
[
{
"id": "8",
"titolo": "View",
"autore": "galleria",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-13 22:55:57",
"foto": "foto\/WP_20161110_001.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/WP_20161110_001.jpg"
},
{
"id": "7",
"titolo": "Storia di Busso",
"autore": "storia",
"testo": "Testo di prova",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-10 21:11:03",
"foto": "foto\/1a3e733334ec8948b0328af4e5b7288a.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/1a3e733334ec8948b0328af4e5b7288a.jpg"
},
{
"id": "6",
"titolo": "Test 2",
"autore": "ricette",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:49:56",
"foto": "foto\/test_2.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/test_2.jpg"
},
{
"id": "5",
"titolo": "Test",
"autore": "eventi",
"testo": "",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:47:53",
"foto": "foto\/coastal-wash-web.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/coastal-wash-web.jpg"
},
{
"id": "4",
"titolo": "Immagine di prova",
"autore": "luoghi",
"testo": "",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-08 10:24:46",
"foto": "foto\/unnamed.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/unnamed.jpg"
},
{
"id": "3",
"titolo": "Panorama",
"autore": "galleria",
"testo": "",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-07 11:21:53",
"foto": "foto\/WP_20161110_001.jpg",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/WP_20161110_001.jpg"
},
{
"id": "2",
"titolo": "Comune di Busso",
"autore": "contatti",
"testo": "Indirizzo, telefono, mail, altri dati da inserire",
"data": "italiano",
"extra1": "",
"extra2": "",
"creazione": "2021-01-01 19:33:56",
"foto": "foto\/DSCN0914.JPG",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/DSCN0914.JPG"
},
{
"id": "1",
"titolo": "Chiesa",
"autore": "commercio",
"testo": "Testo di prova, abbastanza lungo per verificare l'impaginazione e correggere eventuali errori.",
"data": "english",
"extra1": "",
"extra2": "",
"creazione": "2021-01-01 19:32:02",
"foto": "foto\/CAM_0044.JPG",
"fotoUrl": "http:\/\/geniuspointfrezza.altervista.org\/foto\/CAM_0044.JPG"
}
]
下载管理器代码如下:
import SwiftUI
import Combine
class DownloadManager: ObservableObject {
@Published var JSON: [BussoModel] = []
@Published var searchText: String = "" {
didSet {
self.searchResults = self.JSON.filter { [=13=].titolo.contains(self.searchText) }
}
}
@Published var searchResults: [BussoModel] = []
init() {
let url = URL(string: "https://geniuspointfrezza.altervista.org/index.php?json=1")!
URLSession.shared.dataTask(with: url) {(data, response, error) in
do {
if let bussoData = data {
let decodedData = try JSONDecoder().decode([BussoModel].self, from: bussoData)
DispatchQueue.main.async {
self.JSON = decodedData
}
} else {
print("No data")
}
} catch {
print(error)
}
}.resume()
}
}
根据您的评论,我相信这就是您想要做的(除非我误解了什么)。我从代码中删除了 URL 图片,因此您必须将其添加回来。
几个注意事项:
- 尝试在 DownloadManager 中进行所有过滤和数据管理。我添加了一个过滤器函数,它在数据下载时以及视图初始化时调用。
- 尽量避免将字符串硬编码到您的代码中。我创建了一个将处理“英语”和“意大利语”过滤器的语言枚举。
- 如果您 运行 在代码中复制了整个部分(例如在 post 中您重写了“it”和“else”的视图),那么肯定有更好的方法。
.
import SwiftUI
//import URLImage
struct HistoryView: View {
@ObservedObject var dm: DownloadManager
let title: String
init(dm: DownloadManager, autore: String) {
self.dm = dm
dm.filter(autore: autore)
self.title = "\(autore)".capitalized + " di Busso"
}
var body: some View {
List {
if !dm.searchResults.isEmpty && !dm.isLoading {
ForEach(dm.searchResults) { busso in
NavigationLink(
destination: Text(busso.titolo)) {
HStack {
Text(busso.fotoUrl)
Text(busso.titolo)
.font(.headline)
Spacer(minLength: 0)
}
.frame(maxWidth: .infinity)
.frame(height: 50)
}
}
} else if dm.isLoading {
ProgressView()
} else {
Text("No results.")
}
}
.navigationTitle(title)
}
}
struct HistoryView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
HistoryView(dm: DownloadManager(), autore: "galleria")
}
}
}
import SwiftUI
import Combine
class DownloadManager: ObservableObject {
@Published private(set) var JSON: [BussoModel] = []
@Published private(set) var isLoading: Bool = true
@Published private(set) var searchAutore: String?
@Published private(set) var searchResults: [BussoModel] = []
let language: Language
enum Language: String {
case italian
case english
}
init() {
language = NSLocale.current.languageCode == "it" ? .italian : .english
getData()
}
private func getData() {
let url = URL(string: "https://geniuspointfrezza.altervista.org/index.php?json=1")!
URLSession.shared.dataTask(with: url) {(data, response, error) in
do {
if let bussoData = data {
let decodedData = try JSONDecoder().decode([BussoModel].self, from: bussoData)
DispatchQueue.main.async {
self.JSON = decodedData
self.isLoading = false
self.filter(autore: self.searchAutore)
}
} else {
print("No data")
self.isLoading = false
}
} catch {
print(error)
self.isLoading = false
}
}.resume()
}
func filter(autore: String?) {
searchAutore = autore
searchResults = JSON.filter({ (bussoModel) -> Bool in
return bussoModel.data == language.rawValue && (bussoModel.autore == searchAutore)
})
}
}
struct BussoModel: Codable, Identifiable {
let id: String
let titolo: String
let autore: String
let testo: String
let data: String
let extra1: String
let extra2: String
let creazione: String
let foto: String
let fotoUrl: String
}