首页 > 解决方案 > 为什么无法在 Swift Project 中访问我的模型类?

问题描述

如何从 ViewController 访问我的模型并使用模型数据加载到表视图中????

源代码链接

我的 ViewController 看起来像这样

import UIKit

class ViewController: UIViewController {
    var cclm: CountryCodeListModel?

    override func viewDidLoad() {
        super.viewDidLoad()
        Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(hello), userInfo: nil, repeats: true)
        readLocalJSONFile(forName: "countryList")

        // Do any additional setup after loading the view.
    }

    override func viewDidAppear(_ animated: Bool) {
        
    }
    
    @objc func hello()
     {
        print(cclm?.data?[0].flag)
     }

}

我的模型类看起来像这样

struct CountryCodeList : Decodable {
    var alpha2Code: String?
    var alpha3Code: String?
    var flag      : String?
    var name      : String?
    var code      : String?
}

public struct CountryCodeListModel : Decodable {
    var data      : [CountryCodeList]?
}

var cclm: CountryCodeListModel?


//Method to load json

func readLocalJSONFile(forName name: String) {
    do {
        if let filePath = Bundle.main.path(forResource: name, ofType: "json") {
            let fileUrl = URL(fileURLWithPath: filePath)
            let data = try Data(contentsOf: fileUrl)
            if let countryCodeObject = parse(jsonData: data) {
                cclm = countryCodeObject
                print(cclm?.data?[1].alpha2Code ?? "")  //Printing Correct Value
            }
        }
    } catch {
        print("error: \(error)")
    }
}



func parse(jsonData: Data) -> CountryCodeListModel?{
    var dataArray : [Dictionary<String,Any>] = [[:]]
    var country = Dictionary<String,Any>()
    var modelData = Dictionary<String,Any>()
    do {
        // make sure this JSON is in the format we expect
        if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? Dictionary<String,Any> {
            dataArray.removeAll()
            for item  in json["data"] as! [Dictionary<String, Any>] {
                country = item
                
                let url = URL(string: country["flag"] as? String ?? "")
                let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
                let image = UIImage(data: data!)
                let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                let fileName = url?.lastPathComponent // name of the image to be saved
                let fileURL = documentsDirectory.appendingPathComponent(fileName ?? "")
                if let data = image?.jpegData(compressionQuality: 1.0){
                    do {
                        try data.write(to: fileURL)
                        country["flag"] = fileURL.absoluteString
                        //print("file saved")
                        //urlAsString = fileURL.absoluteString
                    } catch {
                        print("error saving file:", error)
                    }
                }
                
                dataArray.append(country)
                country.removeAll()
                
                    
                
            }
            modelData["data"] = dataArray
            //print(modelData)
            let jsonData1 = try JSONSerialization.data(withJSONObject: modelData, options: [])
            
            do {
                    let decodedData = try JSONDecoder().decode(CountryCodeListModel.self, from: jsonData1)
                
                    return decodedData
                } catch {
                    print("error: \(error)")
                }
            
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
    return nil
}

问题陈述:

我正在读取本地 json 并获取标志键的 url 值并将相应的图像下载到本地。一旦我下载然后获取本地路径并在字典中更新,然后创建 JSON 对象并更新我的模型类。

现在,我试图从 ViewController 访问我的模型类,如下所示

print(CountryCodeListModel?.data?[0].name) //check screenshot for error
 print(cclm?.data?[0].flag)                 // this prints nil always

请检查附上的错误截图2

我的 JSON 看起来像这样

{
   "meta":{
      "success":true,
      "message":"Successfully retrieved country details",
      "code":"200"
   },
   "data":[
      {
         "alpha2Code":"AF",
         "alpha3Code":"AFG",
         "flag":"https://raw.githubusercontent.com/DevTides/countries/master/afg.png",
         "name":"Afghanistan",
         "code":"+93"
      },
      {
         "alpha2Code":"AX",
         "alpha3Code":"ALA",
         "flag":"https://raw.githubusercontent.com/DevTides/countries/master/ala.png",
         "name":"Aland Islands",
         "code":"+358"
      },
      {
         "alpha2Code":"AL",
         "alpha3Code":"ALB",
         "flag":"https://raw.githubusercontent.com/DevTides/countries/master/alb.png",
         "name":"Albania",
         "code":"+355"
      },
      {
         "alpha2Code":"DZ",
         "alpha3Code":"DZA",
         "flag":"https://raw.githubusercontent.com/DevTides/countries/master/dza.png",
         "name":"Algeria",
         "code":"+213"
      },
      {
         "alpha2Code":"AS",
         "alpha3Code":"ASM",
         "flag":"https://raw.githubusercontent.com/DevTides/countries/master/asm.png",
         "name":"American Samoa",
         "code":"+1684"
      }
]
}

标签: iosjsonswiftuitableviewnsdictionary

解决方案


您正在尝试解码不存在的东西。

print(CountryCodeListModel?.data?[0].name) //check screenshot for error
 print(cclm?.data?[0].flag)                 // this prints nil always

上面的代码表明你想要:

  1. 的名字
  2. 位置 0 的变量数据
  3. 结构CountryCodeListModel

你想做的是:

  1. 的名字
  2. 位置 0 的变量
  3. 结构的实例CountryCodeListModel

例如...

func readLocalJSONFile(forName name: String) {
    do {
        if let filePath = Bundle.main.path(forResource: name, ofType: "json") {
            let fileUrl = URL(fileURLWithPath: filePath)
            let data = try Data(contentsOf: fileUrl)
            if let countryCodeObject = parse(jsonData: data) {
                cclm = countryCodeObject
                print(cclm?.data?[1].alpha2Code ?? "")  //Printing Correct Value
                print(cclm?.data?[0].flag ?? "")
                print(countryCodeObject?.data[0].flag ?? "") // Same as the line above
            }
        }
    } catch {
        print("error: \(error)")
    }
}

除非您尝试使用static变量(您将使用CountryCodeListModel.data),否则您需要确保您实际使用的是结构的实例或类的对象来引用您的属性。

警告

CountryCodeListModel是一个结构。CountryCodeListModel()是结构的一个实例CountryCodeListModel。由于您可以拥有结构的多个实例,因此在访问数据时需要引用特定的结构。因此,CountryCodeListModel.data将不起作用,它需要是CountryCodeListModel().data。在这种情况下,您有cclm.data.


推荐阅读