Итак, я получаю данные альбома по идентификатору в моем приложении.
1-й:
Получение данных (включая все идентификаторы) из базы данных
class Webservice {
func getAllPosts(completion: @escaping ([Post]) -> ()) {
guard let url = URL(string: "http://localhost:8000/albums")
else {
fatalError("URL is not correct!")
}
URLSession.shared.dataTask(with: url) { data, _, _ in
let posts = try!
JSONDecoder().decode([Post].self, from: data!); DispatchQueue.main.async {
completion(posts)
}
}.resume()
}
}
Переменные
struct Post: Codable, Hashable, Identifiable {
let id: String
let title: String
let path: String
let description: String
}
Установка переменных для данных из Webservice
final class PostListViewModel: ObservableObject {
init() {
fetchPosts()
}
@Published var posts = [Post]()
private func fetchPosts() {
Webservice().getAllPosts {
self.posts = $0
}
}
}
2nd:
Вот так я получаю данные моего альбома по id
class SecondWebService: Identifiable {
var id:String = ""
init(id: String?) {
self.id = id!
}
func getAllPostsById(completion: @escaping ([PostById]) -> ()) {
guard let url = URL(string: "http://localhost:8000/albums/\(id)")
else {
fatalError("URL is not correct!")
}
URLSession.shared.dataTask(with: url) { data, _, _ in
let posts = try!
JSONDecoder().decode([PostById].self, from: data!); DispatchQueue.main.async {
completion(posts)
}
}.resume()
}
}
Переменные
struct PostById: Codable, Hashable, Identifiable {
let id: String
let name: String?
let path: String
}
Установите переменные для данных, которые я получил от SecondWebService. Я считаю, что это будет срабатывать только тогда, когда я получаю сообщения от модели (PostListViewModel ()), создающей сообщения. Как и раньше, это не работало, потому что я не получал данные из постов, потому что, когда @ObservedObject var model = PostListViewModel()
был просто создан в class PostListViewByIdModel
, и он не получал данные сразу
final class PostListViewByIdModel: ObservableObject {
init() {
}
@Published var postsById = [PostById]()
func fetchPostsById(for posts: [Post]) {
for post in posts {
SecondWebService(id: post.id).getAllPostsById {
self.postsById = $0
}
}
}
}
Вот как я исправил проблему, связанную с невозможностью получить данные сразу:
struct ContentView: View {
@ObservedObject var model = PostListViewModel()
@ObservedObject var model2 = PostListViewByIdModel()
var body: some View {
NavigationView {
List(model.posts) { post in
VStack{
Text("Title: ").bold()
+ Text("\(post.title)")
NavigationLink(destination: Album(post: post)) {
ImageView(withURL: "http://localhost:8000/\(post.path.replacingOccurrences(of: " ", with: "%20"))")
}
Text("Description: ").bold()
+ Text("\(post.description)")
}
}
}
.onReceive(model.$posts) { posts in // << first got finished
self.model2.fetchPostsById(for: posts) // << start second
}
.onReceive(model2.$postsById) { postById in
print(postById)
}
}
}
Здесь я добавляю onRecieve
для модели (PostListViewModel ()) model.posts
и когда я получаю данные, передача сообщений в мою функцию fetchPostsById(for posts: [Post])
в PostListViewByIdModel()
дает мне доступ к идентификатору.
func fetchPostsById(for posts: [Post]) {
for post in posts {
SecondWebService(id: post.id).getAllPostsById {
self.postsById = $0
}
}
Это работает, поскольку я могу использовать свои данные, которые я получил от своей функции во время второго включения onRecieve, как вы можете видеть:
.onReceive(model2.$postsById) { postById in
print(postById)
}
Это замечательно, но, как вы можете видеть, У меня есть Album(post: post)
, который является структурой и представлением SwiftUI.
struct Album: View {
var post:Post
var body: some View {
VStack {
Text("Title: ").bold()
+ Text("\(post.title)")
ImageView(withURL: "http://localhost:8000/\(post.path.replacingOccurrences(of: " ", with: "%20"))")
Text("Description: ").bold()
+ Text("\(post.description)")
}
}
}
Здесь я получаю доступ к своим данным из первого кода, но я также хочу добавить свои данные из второй части кода здесь с использованием списка вроде
List(post2) { post in
Text("\(post.id)")
}
Так как я могу получить доступ к postById из моего второго метода onRecieve, чтобы вставить этот код?