I have tried to do this so many ways but the swift compiler complains whatever I do. SourceKit and the compiler also crashes non-stop, so I can't even experiment anymore. Not even to insert some println
s. I'm tearing my hair.
I'm trying to construct a simple array for table view content. The "rows" are Presentable
objects, which is just a collection of protocols.
import Foundation
// The protocols are all @objc
typealias Presentable = protocol<Utterable, Displayable, Departure>
typealias TableSection = (sectionTitle: String, rows: [Presentable])
1. This doesn't work:
(buses, metros
etc. are all [Bus]?, [Metro]?
etc. and those classes conform to all the protocols that are Presentable
)
private func asContent5() -> [TableSection]
{
var result: Array<TableSection> = []
var deptsCollections: [[Presentable]?] = [ buses, metros, trains, trams, ships ]
for var i = 0; i<deptsCollections.count ; i++ {
if let departures = deptsCollections[i]? {
var newDeparturesArray: [Presentable] = []
for dep in departures
{
newDeparturesArray.append(dep) // EXC_BAD_INSTRUCTION
}
let tuple: TableSection = (sectionTitle: "test", rows: newDeparturesArray)
result.append(tuple)
}
}
return result
}
Console output:
fatal error: NSArray element failed to match the Swift Array Element type
2. This "works" (i.e. doesn't crash at runtime) but I seem to get no objects in my new array:
private func asContent4() -> [TableSection]
{
var result: Array<TableSection> = []
var deptsCollections: [AnyObject?] = [ buses, metros, trains, trams, ships ]
for var i = 0; i<deptsCollections.count ; i++ {
if let departures: [Presentable] = deptsCollections[i] as? [Presentable] {
var newDeparturesArray: [Presentable] = []
for dep in departures
{
newDeparturesArray.append(dep as Presentable)
}
let tuple: TableSection = (sectionTitle: "test", rows: newDeparturesArray)
result.append(tuple)
}
}
return result
}
3. This works fully:
private func asContent3() -> [TableSection]
{
var result: Array<TableSection> = []
if let departures = buses {
var newDeparturesArray: [Presentable] = []
for dep in departures { newDeparturesArray.append(dep as Presentable) }
let tuple: TableSection = (sectionTitle: "bus", rows: newDeparturesArray)
result.append(tuple)
}
if let departures = metros {
var newDeparturesArray: [Presentable] = []
for dep in departures { newDeparturesArray.append(dep as Presentable) }
let tuple: TableSection = (sectionTitle: "metro", rows: newDeparturesArray)
result.append(tuple)
}
if let departures = trains {
var newDeparturesArray: [Presentable] = []
for dep in departures { newDeparturesArray.append(dep as Presentable) }
let tuple: TableSection = (sectionTitle: "trains", rows: newDeparturesArray)
result.append(tuple)
}
if let departures = trams {
var newDeparturesArray: [Presentable] = []
for dep in departures { newDeparturesArray.append(dep as Presentable) }
let tuple: TableSection = (sectionTitle: "trams", rows: newDeparturesArray)
result.append(tuple)
}
if let departures = ships {
var newDeparturesArray: [Presentable] = []
for dep in departures { newDeparturesArray.append(dep as Presentable) }
let tuple: TableSection = (sectionTitle: "ships", rows: newDeparturesArray)
result.append(tuple)
}
return result
}
All I want is to take my buses, metros, trains, trams, ships
and put them in a [Presentable]
each, without a wall of code. I'm starting to believe it's impossible in Swift, because it feels like I've rewritten these loops in every conceivable way.
What am I missing? Why can't I seem to iterate successfully instead of repeating all this code?
Update
This is what happens with Davids code:
Same console output as above, but this time it crashes when trying to access the TableSection::rows (that has happened to me before as well). This makes it crash:
println("index path s: \(indexPath.section) r: \(indexPath.row)")
let section = tableContent[indexPath.section]
println("row count: \(section.rows.count)")
let departure: Presentable = section.rows[indexPath.row] // crash
Console (I printed the rows
array from the Variables View):
index path s: 0 r: 0
row count: 8
fatal error: NSArray element failed to match the Swift Array Element type
Printing description of section.rows:
([protocol<Departure, Displayable, Utterable>]) rows = {}
Is it just me or don't these numbers add up?