diff --git a/Sources/Parsers/StoryboardParser.swift b/Sources/Parsers/StoryboardParser.swift index 5ece2ed..f849060 100644 --- a/Sources/Parsers/StoryboardParser.swift +++ b/Sources/Parsers/StoryboardParser.swift @@ -28,9 +28,16 @@ public final class StoryboardParser { let customModule: String? } + struct Cell { + let identifier: String + let customClass: String? + let customModule: String? + } + var initialScenes = [String: InitialScene]() var storyboardsScenes = [String: Set]() var storyboardsSegues = [String: Set]() + var storyboardsCells = [String: Set]() var modules = Set() public init() {} @@ -40,10 +47,13 @@ public final class StoryboardParser { var initialScene: InitialScene? var scenes = Set() var segues = Set() + var cells = Set() var inScene = false var readyForFirstObject = false var readyForConnections = false + var readyForTableView = false + // swiftlint:disable cyclomatic_complexity @objc func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String: String]) { @@ -71,6 +81,14 @@ public final class StoryboardParser { customModule: customModule)) } readyForFirstObject = false + case "tableView": + readyForTableView = true + case "tableViewCell" where readyForTableView: + if let reuseIdentifier = attributeDict["reuseIdentifier"] { + let customClass = attributeDict["customClass"] + let customModule = attributeDict["customModule"] + cells.insert(Cell(identifier: reuseIdentifier, customClass: customClass, customModule: customModule)) + } case "connections": readyForConnections = true case "segue" where readyForConnections: @@ -83,6 +101,7 @@ public final class StoryboardParser { break } } + // swiftlint:enable cyclomatic_complexity @objc func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { @@ -91,6 +110,8 @@ public final class StoryboardParser { inScene = false case "objects" where inScene: readyForFirstObject = false + case "tableView": + readyForTableView = false case "connections": readyForConnections = false default: @@ -110,6 +131,7 @@ public final class StoryboardParser { initialScenes[storyboardName] = delegate.initialScene storyboardsScenes[storyboardName] = delegate.scenes storyboardsSegues[storyboardName] = delegate.segues + storyboardsCells[storyboardName] = delegate.cells modules.formUnion(collectModules(initial: delegate.initialScene, scenes: delegate.scenes, segues: delegate.segues)) } @@ -163,3 +185,18 @@ extension StoryboardParser.Segue: Hashable { return identifier.hashValue ^ (customModule?.hashValue ?? 0) ^ (customClass?.hashValue ?? 0) } } + +extension StoryboardParser.Cell: Equatable { } +func == (lhs: StoryboardParser.Cell, rhs: StoryboardParser.Cell) -> Bool { + return lhs.identifier == rhs.identifier && + lhs.customClass == rhs.customClass && + lhs.customModule == rhs.customModule +} + +extension StoryboardParser.Cell: Hashable { + var hashValue: Int { + // swiftlint:disable line_length + return identifier.hashValue ^ (customModule?.hashValue ?? 0) ^ (customClass?.hashValue ?? 0) ^ (customClass?.hashValue ?? 0) + // swiftlint:enable line_length + } +} diff --git a/Sources/Stencil/StoryboardsContext.swift b/Sources/Stencil/StoryboardsContext.swift index 711ef24..b256406 100644 --- a/Sources/Stencil/StoryboardsContext.swift +++ b/Sources/Stencil/StoryboardsContext.swift @@ -36,8 +36,10 @@ private func uppercaseFirst(_ string: String) -> String { - `class`: `String` (absent if generic UIStoryboardSegue) */ extension StoryboardParser { + // swiftlint:disable function_body_length public func stencilContext(sceneEnumName: String = "StoryboardScene", - segueEnumName: String = "StoryboardSegue") -> [String: Any] { + segueEnumName: String = "StoryboardSegue", + cellEnumName: String = "StoryboardCells") -> [String: Any] { let storyboards = Set(storyboardsScenes.keys).union(storyboardsSegues.keys).sorted(by: <) let storyboardsMap = storyboards.map { (storyboardName: String) -> [String:Any] in var sbMap: [String:Any] = ["name": storyboardName] @@ -60,7 +62,7 @@ extension StoryboardParser { if let scenes = storyboardsScenes[storyboardName] { sbMap["scenes"] = scenes .sorted(by: {$0.storyboardID < $1.storyboardID}) - .map { (scene: Scene) -> [String:Any] in + .map { (scene: Scene) -> [String: Any] in if let customClass = scene.customClass { return [ "identifier": scene.storyboardID, @@ -81,17 +83,29 @@ extension StoryboardParser { } // All Segues if let segues = storyboardsSegues[storyboardName] { - sbMap["segues"] = segues - .sorted(by: {$0.identifier < $1.identifier}) - .map { (segue: Segue) -> [String:String] in - ["identifier": segue.identifier, "customClass": segue.customClass ?? ""] - } + sbMap["segues"] = segues + .sorted(by: {$0.identifier < $1.identifier}) + .map { (segue: Segue) -> [String: String] in + ["identifier": segue.identifier, "customClass": segue.customClass ?? ""] + } } + + // All Segues + if let cells = storyboardsCells[storyboardName] { + sbMap["cells"] = cells + .sorted(by: {$0.identifier < $1.identifier}) + .map { (cell: Cell) -> [String: String] in + ["identifier": cell.identifier, "customClass": cell.customClass ?? ""] + } + } + return sbMap } + return [ "sceneEnumName": sceneEnumName, "segueEnumName": segueEnumName, + "cellEnumName": cellEnumName, "storyboards": storyboardsMap, "modules": modules.sorted(), @@ -99,4 +113,5 @@ extension StoryboardParser { "extraImports": modules.sorted() ] } + // swiftlint:enable function_body_length } diff --git a/Tests/Resources b/Tests/Resources index 35a8748..6a243cb 160000 --- a/Tests/Resources +++ b/Tests/Resources @@ -1 +1 @@ -Subproject commit 35a8748f00c11859505ae83e943abb7318919487 +Subproject commit 6a243cb9b1309ad3b6618318d805e9719670ed7b