首页 > 解决方案 > 如何从已实现的 PLIST 字典中访问项目?

问题描述

我已经从 plist 中提取项目并将它们实现到字典中,但是我不太确定如何解包并使这些项目可从变量中使用。这是我所拥有的:

import UIKit

class ViewController: UIViewController,
    UITableViewDataSource {

   // Loading in the PLIST file
   override func viewDidLoad() {
    super.viewDidLoad()
   }
    var courses = loadCSCourses()

    //variables
    var courseData = courses["CS 1400"]
    var shortDescription = courseData["ShortDescription"]
    var courseKeys = Array(courses.keys)
    @IBOutlet weak var mySwitch: UISwitch!
    @IBOutlet weak var tableView: UITableView!
    @IBAction func whenSwitchOn (sender:AnyObject) {
        if (mySwitch.isOn){
            self.tableView.reloadData()
        }
    }

    func sortingCourseKeys() {
        courseKeys.sort()
    }
    // The number of rows
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return courses!.count
    }

    // The number of cells in each row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        //Naming the Title and Subtitle line
        cell.textLabel?.text = "course name"
        cell.detailTextLabel?.text = "course description"
        cell.accessoryType = .checkmark

        return cell
    }

    // Selecting and deslecting rows
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = courseKeys[indexPath.row]
        if cell.contains(courseKeys[indexPath.row]) {
            cell.accessoryType = .checkmark
        }else{
            cell.accessoryType = .none
        }
        return
    }
}

func loadCSCourses() -> [String : [String : String]]? {
    let pListFileURL = Bundle.main.url(forResource: "CSCourses", withExtension: "plist", subdirectory: "")
    if let pListPath = pListFileURL?.path,
        let pListData = FileManager.default.contents(atPath: pListPath) {
        do {
            let pListObject = try PropertyListSerialization.propertyList(from: pListData, options:PropertyListSerialization.ReadOptions(), format:nil)
            guard let maybeCourses = pListObject as? [String : [String : String]] else {
                return nil
            }
            return maybeCourses
        } catch {
            print("Error reading CSCourses plist file: \(error)")
            return nil
        }
    }
    return nil
}

我收到错误消息:不能在属性初始化程序中使用实例成员“课程”;属性初始值设定项在“self”可用和可选类型“[String : [String : String]] 的值?”之前运行 必须解包以引用已包装基类型“[String : [String : String]]”的成员“下标”

任何提示、链接或帮助将不胜感激。多谢你们。

标签: iosswiftuiviewcontrollertableviewplist

解决方案


您面临的问题是您在 self 初始化之前使用了类方法。你有几个选择:

覆盖 init 函数并在那里设置你的变量

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    courses = loadCSCourses()
}

使您的变量成为惰性变量

lazy var courses = loadCSCourses()

将函数 loadCSCourses() 设为静态,尽管我不建议这样做。

请记住您定义的方式:

var courseData = courses["CS 1400"]
var shortDescription = courseData["ShortDescription"]
var courseKeys = Array(courses.keys)

也太早了,把这个移到init,在定义self之后(或者按照2.选项)


推荐阅读