The data I pulled from the network appears as [Project Name.modelName (user ID: id: , title: , body: )]. It doesn't show up when I put it in the cell. How can I fix this? Thanks
fetch function
func fetchPosts(completion: @escaping (Result<[Posts],Error>) -> Void){
let url = URL(string:"https://jsonplaceholder.typicode.com/posts")!
URLSession.shared.dataTask(with: url) { data, res, error in
guard let data else{ return }
do{
let posts = try JSONDecoder().decode([Posts].self, from: data)
completion(.success(posts))
print(posts)
}catch{
completion(.failure(NSError()))
}
}.resume()
}
Network json
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}, ...
]
Protocols
protocol UserViewModelOutput: AnyObject{
func updateView(title:[Posts])
}
protocol PostsService{
func fetchPosts(completion: @escaping (Result<[Posts],Error>) -> Void)
}
TableViewController
class ViewController: UIViewController, UserViewModelOutput {
private let viewModel: PostViewModel
var postsArray = [Posts]()
lazy var homeTableView: UITableView = {
let tableView = UITableView()
tableView.delegate = self
tableView.dataSource = self
tableView.register(HomeTableViewCell.self, forCellReuseIdentifier: HomeTableViewCell.reuseIdentifier)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
return tableView
}()
init(viewModel: PostViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
self.viewModel.output = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
fetchUsers()
view.backgroundColor = .yellow
}
private func setupViews() {
NSLayoutConstraint.activate([
homeTableView.topAnchor.constraint(equalTo: view.topAnchor),
homeTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
homeTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
homeTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
func fetchUsers(){
viewModel.fetchPost()
}
func updateView(title: [Posts]) {
self.postsArray = title
}
}
extension ViewController:UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(postsArray.count)
return postsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = homeTableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.reuseIdentifier, for: indexPath)
cell.textLabel?.text = self.postsArray[indexPath.row].title
return cell
}
}
I added the data to the array, but it does not appear and the array count appears to be 0 when I print. When I print the incoming json data, it appears as [ProjectName.modelName (userId: id: , title: , body: )]. Where am I making a mistake? Thank you for your help
Your problem is Binding view to viewmodel (observe), there are a lot of way to set a binding that one of them I mention it:
You can define:
and in Your ViewModel define a variable and a function like:
after that in your fetchPosts function in viewModel:
and in your viewController you should define this function:
and finally you should call it in viewDidLoad: