Как получить или использовать значения из onRecieve Swift - PullRequest
0 голосов
/ 20 марта 2020

Итак, я получаю данные альбома по идентификатору в моем приложении.

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, чтобы вставить этот код?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...