微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MusicBrainz API 数据未显示在 UITableView 中

如何解决MusicBrainz API 数据未显示在 UITableView 中

只是想问问我是否正确调用了 API,因为我的 TableView 中没有显示数据(我是 UIKit 的新手)。我关注了 this tutorial,将其调整为我需要的网址。

我认为问题在于我如何进行 API 调用,因为我的数组仍然为空?我相信这是一个 REST API,所以这可能是问题吗?

我也在以编程方式执行此操作,因此主故事板是空白的。

模型数据:

import Foundation

class ArtistSearchModelData{
   // var artists = [Artists]()

    public func loadArtists(searchTerm: String,completionHandler: @escaping([Artists]) -> Void){
        guard let url = URL(string: "https://musicbrainz.org/ws/2/artist/?query=artist:\(searchTerm)") else {
           print("URL is invalid")
            return
        }
        
        let dataTask = URLSession.shared.dataTask(with: url){ data,response,error in
           if let data = data {
                if let artistResponse = try? JSONDecoder().decode(ArtistResponse.self,from: data){
                    completionHandler(artistResponse.artists ?? [])
                }
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse,(200...299).contains(httpResponse.statusCode) else{
                print("Error with response: \(response)")
                return
            }
            
            if let error = error {
                print("Error Thrown : \(error)")
                return
            }
        }

        dataTask.resume()
    }
}

视图控制器:

import UIKit

class ViewController: UIViewController {

    let tableView = UITableView()
    var safeArea: UILayoutGuide!
    var artists: [Artists]?
 
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        safeArea = view.layoutMarginsGuide

        setUpTable()
        setUpNavigation()
  
    }
    
    func setUpTable(){
        
        ArtistSearchModelData().loadArtists (searchTerm: "Fred"){ [weak self] (artists) in
              self?.artists = artists
              
              dispatchQueue.main.async{
                self?.tableView.reloadData()
              }
        }
        
        view.addSubview(tableView)
                
        //populate with data
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(UITableViewCell.self,forCellReuseIdentifier: "cell")
        
        //turn off autoresizing
        tableView.translatesAutoresizingMaskIntoConstraints = false
        
        //Layout Configs
        tableView.topAnchor.constraint(equalTo: safeArea.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
       
    }
    
    func setUpNavigation(){
        navigationItem.title = "Artists"
        self.navigationController?.navigationBar.barTintColor = .gray
        self.navigationController?.navigationBar.isTranslucent = false
        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
    }

}

extension ViewController: UITableViewDataSource,UITableViewDelegate{
    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        if let artistsCount = artists {
            return artistsCount.count
        }else{
            return 0
        }
    }
    
    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
        cell.textLabel?.text = artists![indexPath.row].id
        return cell
    }
    
    func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100.0
    }
}

型号:

import Foundation

//http://musicbrainz.org/ws/2/artist/?query=artist:SEARCHTERM

struct ArtistResponse: Codable{
    let artists : [Artists]
}

struct Artists: Codable{
    let id: String
    let type: String
    let name: String
    let country: String
    let disambiguation: String
}

应用委托:

import UIKit

@main
class AppDelegate: UIResponder,UIApplicationDelegate {



    func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    // MARK: UIScenesession Lifecycle

    func application(_ application: UIApplication,configurationForConnecting connectingScenesession: UIScenesession,options: UIScene.Connectionoptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration",sessionRole: connectingScenesession.role)
    }

    func application(_ application: UIApplication,diddiscardScenesessions scenesessions: Set<UIScenesession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running,this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes,as they will not return.
    }


}

场景代理:

import UIKit

class SceneDelegate: UIResponder,UIWindowSceneDelegate {

    var window: UIWindow?


    func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard,the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingScenesession` instead).
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    func sceneDiddisconnect(_ scene: UIScene) {
        // Called as the scene is being released by the system.
        // This occurs shortly after the scene enters the background,or when its session is discarded.
        // Release any resources associated with this scene that can be re-created the next time the scene connects.
        // The scene may re-connect later,as its session was not necessarily discarded (see `application:diddiscardScenesessions` instead).
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
    }

    func sceneWillResignActive(_ scene: UIScene) {
        // Called when the scene will move from an active state to an inactive state.
        // This may occur due to temporary interruptions (ex. an incoming phone call).
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data,release shared resources,and store enough scene-specific state information
        // to restore the scene back to its current state.
    }


}

解决方法

由于某些值变为空且未处理,请更新可编码模型并检查其是否有效:

struct ArtistResponse: Codable{
    let artists : [Artist]
}

struct Artist: Codable{
    let id: String?
    let type: String?
    let name: String?
    let country: String?
    let disambiguation: String?
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。