swift 来自网络的数据在ios uikit中的单元格中不可见

rdlzhqv9  于 2023-11-16  发布在  Swift
关注(0)|答案(1)|浏览(114)

我从网络上拉取的数据显示为[Project Name.modelName(user ID:id:,title:,body:)],放入单元格后显示不出来,怎么解决?谢谢
取出函数

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()
    }

字符串
网络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"
  }, ...
]


协议

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
    }
    
    
}


我将数据添加到数组中,但它没有出现,打印时数组计数显示为0。打印传入的json数据时,它显示为[ProjectName.modelName(userId:id:,title:,body:)]。我哪里出错了?谢谢您的帮助

r6hnlfcb

r6hnlfcb1#

你的问题是将视图绑定到视图模型(observe),有很多方法可以设置绑定,其中一种我提到过:
您可以定义:

enum FetchViewModelChange {
    case success
    case error(Error)
}

字符串
在你的ViewModel中定义一个变量和一个函数,如:

var fetchChangeHandler: ((FetchViewModelChange) -> Void)?

func emit(_ change: FetchViewModelChange) {
     fetchChangeHandler?(change)
}


在viewModel中的fetchPosts函数中:

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))
                emit(.success)
                print(posts)
                
            } catch let error {
                completion(.failure(NSError()))
                emit(.error(error))
            }
        }.resume()
    }


在viewController中,你应该定义这个函数:

func bindViewModel() {
        viewModel.fetchChangeHandler = { [weak self] change in
            guard let strongSelf = self else { return }
            switch change {
            case .didSuccess:
                strongSelf.postArray = viewModel.posts
                strongSelf.tableView.reload()
            case .didError(let error):
                debugPrint(error)
            }
        }
    }


最后你应该在viewDidLoad中调用它:

bindViewModel()

相关问题