ios - 使用 Swift 3,如何解析 JSON 文件以便可以全局访问数据?

标签 ios json swift

我是 iOS 开发的新手,如果我使用了不正确的术语,请提前致歉。我正在为一个学校项目开发一个基本的应用程序,非常感谢任何帮助!

我有一个包含 20 个不同对象的 JSON 文件(请参阅下面第一个对象的示例),我想在三个不同的 View Controller 中解析和访问这些对象以用于不同的目的 - 相同的数据,只是在中排序或呈现不同的方式。

JSON 文件本地存储在 xCode 项目中。我如何解析它以便我可以在不同的 View Controller 中全局访问数据?

我的理解是,最好在 AppDelegate Controller 中解析 JSON 文件,然后在每个单独的 ViewController 中调用数据,但我不确定如何以编程方式执行此操作。

JSON 文件的名称是“locations.json”

{
    locations: [

        {
            "id": 0001,
            "name": "Helensburgh Tunnels",
            "type": ["Tunnels", "Beach", "Views"],
            "location": "Helensburgh, South Coast",
            "image": "Helensburgh-Tunnels.jpg",
            "activity": "Walking, photography, tunnelling",
            "isVisited": false,
            "latitude": -34.178985,
            "longitude": 150.992867
        }
}

然后,如果您能详细说明我如何在 TableView 中读取这些数据,我将不胜感激。我的 TableView 单元格当前配置如下(从硬编码到同一个 ViewController 的数组中读取)- 我如何更新它以读取解析的 JSON 数据?

View Controller 名称; LocationTableViewController.swift

var locations:[Location] = [
        Location(name: "Helensburgh Tunnels", type: "Old, abandoned train tunnels.", location: "Helensburgh, South Coast", image: "Helensburgh-Tunnels.jpg", activity: "Walking, photography, tunnelling", isVisited: false, latitude: "-34.178985", longitude: "150.992867")
]

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cellIdentifier = "cell"
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! LocationTableViewCell

    // Configure the cell
    cell.nameLabel.text = locations[indexPath.row].name
    cell.thumbnailImageView.image = UIImage(named: locations[indexPath.row].image)
    cell.locationLabel.text = locations[indexPath.row].location
    cell.typeLabel.text = locations[indexPath.row].type
    cell.accessoryType = locations[indexPath.row].isVisited ? .checkmark : .none
    return cell
}

定位模型如下。 View Controller 的名称;定位.swift

class Location: NSObject, MKAnnotation {
    var name: String = ""
    var type: String = ""
    var location: String = ""
    var image: String = ""
    var activity: String = ""
    var isVisited: Bool = false
    var rating: String = ""
    var latitude: Double = 0.0
    var longitude: Double = 0.0

    init(name: String, type: String, location: String, image: String, activity: String, isVisited: Bool, latitude: String, longitude: String) {
        self.name = name
        self.type = type
        self.location = location
        self.image = image
        self.activity = activity
        self.isVisited = isVisited
        self.latitude = Double(latitude)!
        self.longitude = Double(longitude)!
    }

    public var coordinate: CLLocationCoordinate2D { get {
        let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
        return coordinate
        }
    }

}

最佳答案

创建一个新的 Swift 文件,如 GlobalClass.Swift

在 GlobalClass 中导入 Foundation 和 UIKit 使函数像这样读取位置:-

func readLocation() ->[String:Any]?{
    do {
        if let file = Bundle.main.url(forResource: "locations", withExtension: "json") {
            let data = try Data(contentsOf: file)
            let json = try JSONSerialization.jsonObject(with: data, options: [.mutableContainers])
            if let object = json as? [String: Any] {
                return object
            }
            return nil
        }
    } catch {
        print(error.localizedDescription)
    }
    return nil
}

然后像这样从 TableView 调用这个函数:-

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cellIdentifier = "cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! LocationTableViewCell

        // Configure the cell
        if let locationJson = readLocation(){
            if let locations = locationJson["location"] as? [[String:Any]]{
                cell.nameLabel.text = locations[indexPath.row]["name"] as! String
                cell.thumbnailImageView.image = UIImage(named: (locations[indexPath.row]["image"] as! String))
                cell.locationLabel.text = locations[indexPath.row]["location"] as! String
                cell.typeLabel.text = locations[indexPath.row]["type"] as! String
                cell.accessoryType = (locations[indexPath.row]["isVisited"] as! Bool) ? .checkmark : .none
            }
        }
        return cell
    }

部分的行数应该是

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let locationJson = readLocation(){
            if let locations = locationJson["location"] as? [[String:Any]]{
              return   locations.count
        }
    }
  return 0
}

确保你的位置文件应该是正确的json格式,否则这个函数会抛出错误

关于ios - 使用 Swift 3,如何解析 JSON 文件以便可以全局访问数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44793314/

相关文章:

iOS 委托(delegate)不起作用,无法修复(内部代码): sending data from UITableView to UITextField in another view

ios - 设置按钮的标签值以在单元格单击时取消隐藏

android - NoClassDefFoundError 在带有 Gradle 的 Android 上使用 Jackson 2.2.x

ios - 实现 accessoryButtonTappedForRowWithIndexPath : in Swift 2

在 Swift 中对包含更复杂值的字典进行排序

ios - 'top-down' UITableView 中 UITableViewCell 中的多个按钮

ios - 修改UINavigationBar标题字体和文字颜色的方法

java - 为什么我的 API 和 JSON 应用程序无法在 Android Studio 中运行

json - TypeScript:将原始数据解析为接口(interface)

ios - 为什么 swift 函数这么贵?