[英]Using Swift 3, how can I parse a JSON file so that I can access the data globally?
我是iOS開發的新手,因此如果使用不正確的術語,請提前道歉。 我正在為學校項目開發一個基本應用程序,希望對您有所幫助!
我有一個JSON文件,其中包含20個不同的對象(請參見下面的第一個對象的示例),我想在三個不同的View Controller中解析和訪問這些對象以實現不同的目的-相同的數據,只是以不同的方式排序或表示。
JSON文件存儲在本地的xCode項目中。 如何解析它,以便可以在不同的View Controller中全局訪問數據?
我的理解是,最好在AppDelegate控制器中解析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數據?
ViewController的名稱; 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
}
位置模型如下。 ViewController的名稱; Location.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格式,否則此函數將引發錯誤
我通常不會在AppDelegate上看到這種類型的東西。 你應該盡量少做些
您可能想看看類似MVVM的方法。 您可以創建一個視圖模型,其工作是出售數據的各種排列。 您可以將其創建為單例,但是如果您的應用不太復雜,則可以在每個視圖控制器中實例化視圖模型。
我通常編寫一個數據管理器,負責解析數據並提供一種以模型數組的形式檢索數據的方法。 視圖模型可以在實例化時或根據需要調用datamanager方法。 同樣,對於簡單的項目,您可以直接在viewmodel中進行數據解析。 視圖模型將具有各種方法,視圖控制器將使用這些方法來檢索必要格式的數據。
上面已大大簡化,但應該可以滿足您的需求。
基本流程:
從文件中讀取內容並創建字典
let urlString = Bundle.main.path(forResource: "filename", ofType: "txt")
let url = URL(string: urlString!)
if let url = url {
do {
let data = try Data(contentsOf: url)
let jsonDictionary = try JSONSerialization.jsonObject(with: data, options:[])
// Model creation code here.
} catch {
print("Error : ")
}
}
從jsonDictionary
對象中,您可以構建模型類。 請參考鏈接的,如何解析JSON對象並將其存儲在模型類。
型號:
struct LocationDetails {
var id: Int = 0
var name: String = ""
// Other variables are here
}
經理班:
// Here you can store common properties.
class AppUtils {
class var parsedResponse: [LocationDetails]
}
構造好模型清單之后。 例如[LocationDetails]
。 您必須將其存儲在AppUtils
類parsedResponse
變量中。
var locationDetailsList = [LocationDetails]()
//Your model construction code here.
//Store the array of objects into AppUtils class
AppUtils.parsedResponse = locationDetailsList
像這樣在不同的UIViewController
上訪問模型。
AppUtils.parsedResponse
注意:如果您的應用程序不訪問數據,則不要將值始終保存在內存中。 盡可能嘗試清理內存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.