很抱歉,如果已经提出此问题,但我还没有找到解决方法。我是Swift的新手所以请耐心等待。我无法弄清楚为什么我一直收到线程1:致命错误:索引超出范围的错误。我之前使用过相同的方法来显示我之前从未遇到过问题的txt文件,所以这是第一次。我正在尝试将坐标显示为文本详细信息,日期和时间作为单元格本身的文本。
Date and Time
Latitude, Longitude
如上所述(想象一下它在一个单元格中)
以下是我的程序代码
import UIKit
import MapKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Array to store the list
var storeCoordinates = [String: String]()
var arrayClient = NSMutableArray()
var readings: [String] = [" "]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Get path of where the file is
let path = Bundle.main.path(forResource: "gps_coords", ofType: "csv")
//Use filemanager to check if the file exist to avoid crashing if it doesn't exist
let fileMgr = FileManager.default
//Display the number of line counts we have
if fileMgr.fileExists(atPath: path!){
do {
let fulltext = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
readings = fulltext.components(separatedBy: "\n") as [String]
for i in 0..<readings.count{
let listData = readings[i].components(separatedBy: ";") as [String]
storeCoordinates["Latitude"] = "\(listData[0])"
storeCoordinates["Longitude"] = "\(listData[1])"
storeCoordinates["DateAndTime"] = "\(listData[2])"
arrayClient.add(storeCoordinates)
}
} catch let error as NSError {
print("Error: \(error)")
}
}
self.title = "Number of entries: \(arrayClient.count)"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row] as AnyObject
cell.textLabel?.text = "\(client.object(forKey: "DateAndTime")!)"
cell.detailTextLabel?.text = "\(client.object(forKey: "Latitude")!) \(client.object(forKey: "Longitude")!)"
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
我遇到的错误是storeCoordinates["Latitude"] = "\(listData[0])"
使用断点,它显示Latitude值与Longitude和DateAndTime一起不为空,但如果我尝试在模拟器中运行应用程序,则会出现错误线程1:致命错误:索引超出范围。到目前为止,没有运气试图弄清楚如何解决这个问题。如果你能帮我搞清楚,那对我来说意味着很多。拜托,谢谢你。
答案 0 :(得分:0)
正如 @vadian 中提到的评论一样,您不可能获得第0个索引。但是你添加了一些支票。
按以下方式更新您的代码:
有些更新 -
使用基于swift的数组
[[String: String]]
而不是NSMutableArray
为每个循环周期初始化
storeCoordinates
并检查您的listData
是否包含3件以上的商品
class AViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//Array to store the list
var arrayClient = [[String: String]]()
var readings: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
//Get path of where the file is
let path = Bundle.main.path(forResource: "gps_coords", ofType: "csv")
//Use filemanager to check if the file exist to avoid crashing if it doesn't exist
let fileMgr = FileManager.default
//Display the number of line counts we have
if fileMgr.fileExists(atPath: path!){
do {
let fulltext = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
readings = fulltext.components(separatedBy: "\n") as [String]
for i in 0..<readings.count {
// Check if you can get data from `readings[i]`
let listData = readings[i].components(separatedBy: ";") as [String]
if listData.count == 3 {
var storeCoordinates = [String: String]()
storeCoordinates["Latitude"] = "\(listData[0])"
storeCoordinates["Longitude"] = "\(listData[1])"
storeCoordinates["DateAndTime"] = "\(listData[2])"
arrayClient.append(storeCoordinates)
}
}
} catch let error as NSError {
print("Error: \(error)")
}
}
self.title = "Number of entries: \(arrayClient.count)"
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row]
if let dateTime = client["DateAndTime"], let latitude = client["DateAndTime"], let longitude = client["DateAndTime"] {
cell.textLabel?.text = "\(dateTime)"
cell.detailTextLabel?.text = "\(latitude) \(longitude)"
}
return cell
}
}
答案 1 :(得分:0)
我认为不可靠的CSV格式是问题的根源。
这是一个使用更好格式(JSON)和更强大的数据源的快速教程。
Resources
文件夹中。将以下代码粘贴到Playground中,它基于您的代码来解析CSV。它将CSV转换为JSON并在桌面上创建文件gps_coords.json
。如果缺少任何字段,您将收到致命错误。
struct Coordinate : Encodable {
let latitude, longitude, dateAndTime : String
}
let url = Bundle.main.url(forResource: "gps_coords", withExtension: "csv")!
let fulltext = try! String(contentsOf: url, encoding: .utf8)
let lines = fulltext.components(separatedBy: .newlines)
let coordinates = lines.map { paragraph -> Coordinate in
let components = paragraph.components(separatedBy: ";")
if components.count != 3 { fatalError("Each line must contain all three fields")}
return Coordinate(latitude: components[0], longitude: components[1], dateAndTime: components[2])
}
do {
let data = try JSONEncoder().encode(coordinates)
let homeURL = URL(fileURLWithPath: NSHomeDirectory())
let destinationURL = homeURL.appendingPathComponent("Desktop/gps_coords.json")
try data.write(to: destinationURL)
} catch { print(error) }
Copy If Needed
)。将ViewController
课程更改为
import UIKit
import MapKit
struct Coordinate : Decodable {
let latitude, longitude, dateAndTime : String
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var arrayClient = [Coordinate]()
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "gps_coords", withExtension: "json")!
let data = try! Data(contentsOf: url)
arrayClient = try! JSONDecoder().decode([Coordinate].self, from: data)
self.title = "Number of entries: \(arrayClient.count)"
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayClient.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let client = arrayClient[indexPath.row]
cell.textLabel?.text = client.dateAndTime
cell.detailTextLabel?.text = client.latitude + " " + client.longitude
return cell
}
}
注意: UITableView
插座缺失,我添加了重新加载数据的行。还要确保在Interface Builder中将delegate
和datasource
从表格视图连接到ViewController
。
删除CSV文件。
新代码使用结构Coordinate
作为数据源,并使用JSONDecoder
非常方便地解码JSON。请注意丢失的类型强制转换和繁琐的密钥订阅以从字典中获取值。