diff --git a/Template/File templates/DataSource.xctemplate/TemplateIcon.png b/Template/File templates/DataSource.xctemplate/TemplateIcon.png
new file mode 100644
index 0000000..4d3d06e
Binary files /dev/null and b/Template/File templates/DataSource.xctemplate/TemplateIcon.png differ
diff --git a/Template/File templates/DataSource.xctemplate/TemplateIcon@2x.png b/Template/File templates/DataSource.xctemplate/TemplateIcon@2x.png
new file mode 100644
index 0000000..4d3d06e
Binary files /dev/null and b/Template/File templates/DataSource.xctemplate/TemplateIcon@2x.png differ
diff --git a/Template/File templates/DataSource.xctemplate/TemplateInfo.plist b/Template/File templates/DataSource.xctemplate/TemplateInfo.plist
new file mode 100644
index 0000000..415a097
--- /dev/null
+++ b/Template/File templates/DataSource.xctemplate/TemplateInfo.plist
@@ -0,0 +1,61 @@
+
+
+
+
+ Kind
+ Xcode.IDEFoundation.TextSubstitutionFileTemplateKind
+ Description
+ Scene data source.
+ Summary
+ Scene data source.
+ SortOrder
+ 30
+ AllowedTypes
+
+ public.swift-source
+
+ DefaultCompletionName
+ Scene
+ MainTemplateFile
+ ___FILEBASENAME___.swift
+ Options
+
+
+ Description
+ The name of the module to create
+ Identifier
+ moduleName
+ Name
+ Module name:
+ NotPersisted
+
+ Required
+
+ Type
+ text
+
+
+ Default
+ ___VARIABLE_moduleName___
+ Identifier
+ productName
+ Type
+ static
+
+
+ Default
+ ___VARIABLE_moduleName___DataSource
+ Description
+ Data source name
+ Identifier
+ dataSourceName
+ Name
+ Data source name:
+ Required
+
+ Type
+ static
+
+
+
+
diff --git a/Template/File templates/DataSource.xctemplate/___FILEBASENAME___DataSource.swift b/Template/File templates/DataSource.xctemplate/___FILEBASENAME___DataSource.swift
new file mode 100644
index 0000000..a13ff80
--- /dev/null
+++ b/Template/File templates/DataSource.xctemplate/___FILEBASENAME___DataSource.swift
@@ -0,0 +1,38 @@
+//
+// ___FILENAME___
+// ___PROJECTNAME___
+//
+// Created by ___FULLUSERNAME___ on ___DATE___.
+// ___COPYRIGHT___
+//
+
+import UIKit
+
+enum ___VARIABLE_dataSourceName___Item {
+ case <#item#>
+}
+
+enum ___VARIABLE_dataSourceName___Section: SectionProtocol {
+ case <#section#>([___VARIABLE_dataSourceName___Item])
+
+ var items: [___VARIABLE_dataSourceName___Item] {
+ switch self {
+ case .<#section#>(let items):
+ return items
+ }
+ }
+}
+
+class ___VARIABLE_dataSourceName___DataSource: DataSourceProtocol {
+ private(set) lazy var sections = [___VARIABLE_dataSourceName___Section]()
+
+ init() {
+ buildSections()
+ }
+}
+
+private extension ___VARIABLE_dataSourceName___DataSource {
+ func buildSections() {
+ sections.removeAll()
+ }
+}
diff --git a/Template/System/Sources/Protocols/DataSourceProtocol.swift b/Template/System/Sources/Protocols/DataSourceProtocol.swift
new file mode 100644
index 0000000..e0edb4c
--- /dev/null
+++ b/Template/System/Sources/Protocols/DataSourceProtocol.swift
@@ -0,0 +1,44 @@
+//
+// DataSourceProtocol.swift
+// O2O
+//
+// Created by Domagoj Kulundzic on 17/07/2018.
+// Copyright © 2018 Martian & Machine. All rights reserved.
+//
+
+import Foundation
+
+protocol DataSourceProtocol {
+ associatedtype Section: SectionProtocol
+ var sections: [Section] { get }
+ var isEmpty: Bool { get }
+}
+
+extension DataSourceProtocol {
+ var isEmpty: Bool {
+ guard numberOfSections() > 0 else {
+ return true
+ }
+ guard sections.first(where: { !$0.items.isEmpty }) != nil else {
+ return true
+ }
+ return false
+ }
+
+ func numberOfSections() -> Int {
+ return sections.count
+ }
+
+ func numberOfItems(in section: Int) -> Int {
+ guard let section = sections[safe: section] else { return 0 }
+ return section.isCollapsed ? 0 : section.items.count
+ }
+
+ func section(at index: Int) -> Section? {
+ return sections[safe: index]
+ }
+
+ func item(at indexPath: IndexPath) -> Section.Item? {
+ return section(at: indexPath.section)?.item(at: indexPath.item)
+ }
+}
diff --git a/Template/System/Sources/Protocols/SectionProtocol.swift b/Template/System/Sources/Protocols/SectionProtocol.swift
new file mode 100644
index 0000000..fef8ffc
--- /dev/null
+++ b/Template/System/Sources/Protocols/SectionProtocol.swift
@@ -0,0 +1,25 @@
+//
+// SectionProtocol.swift
+// O2O
+//
+// Created by Domagoj Kulundzic on 17/07/2018.
+// Copyright © 2018 Martian & Machine. All rights reserved.
+//
+
+import Foundation
+
+protocol SectionProtocol {
+ associatedtype Item
+ var items: [Item] { get }
+ var isCollapsed: Bool { get }
+}
+
+extension SectionProtocol {
+ var isCollapsed: Bool {
+ return false
+ }
+
+ func item(at index: Int) -> Item? {
+ return items[safe: index]
+ }
+}
diff --git a/Template/Template.xcodeproj/project.pbxproj b/Template/Template.xcodeproj/project.pbxproj
index f958de9..ceae7d9 100644
--- a/Template/Template.xcodeproj/project.pbxproj
+++ b/Template/Template.xcodeproj/project.pbxproj
@@ -55,6 +55,8 @@
482201BD22982422003319F0 /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 482201A822982422003319F0 /* System.framework */; };
482201BE22982422003319F0 /* System.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 482201A822982422003319F0 /* System.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
482201CF2298252D003319F0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 482201CE2298252D003319F0 /* LaunchScreen.storyboard */; };
+ 488240552349447000CB6FFE /* SectionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488240532349447000CB6FFE /* SectionProtocol.swift */; };
+ 488240562349447000CB6FFE /* DataSourceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488240542349447000CB6FFE /* DataSourceProtocol.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -214,6 +216,8 @@
482201B722982422003319F0 /* SystemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemTests.swift; sourceTree = ""; };
482201B922982422003319F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
482201CE2298252D003319F0 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ 488240532349447000CB6FFE /* SectionProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionProtocol.swift; sourceTree = ""; };
+ 488240542349447000CB6FFE /* DataSourceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataSourceProtocol.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -538,6 +542,7 @@
482201C822982451003319F0 /* Sources */ = {
isa = PBXGroup;
children = (
+ 488240522349446600CB6FFE /* Protocols */,
480E55FF229BEFC20031BDF7 /* AttributedStringBuilder.swift */,
480E5602229BEFE20031BDF7 /* Broadcast.swift */,
480E5601229BEFE20031BDF7 /* BroadcastObjectWrapper.swift */,
@@ -633,6 +638,15 @@
path = Scenes;
sourceTree = "";
};
+ 488240522349446600CB6FFE /* Protocols */ = {
+ isa = PBXGroup;
+ children = (
+ 488240542349447000CB6FFE /* DataSourceProtocol.swift */,
+ 488240532349447000CB6FFE /* SectionProtocol.swift */,
+ );
+ path = Protocols;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -990,12 +1004,14 @@
buildActionMask = 2147483647;
files = (
480E56BE229C14970031BDF7 /* ExampleNavigationViewController.swift in Sources */,
+ 488240552349447000CB6FFE /* SectionProtocol.swift in Sources */,
480E55F3229BEE6F0031BDF7 /* UICollectionView-Template.swift in Sources */,
480E55FC229BEF550031BDF7 /* URL-Template.swift in Sources */,
480E55FA229BEF430031BDF7 /* Collection-Template.swift in Sources */,
480E5689229C04BD0031BDF7 /* ExampleContentView.swift in Sources */,
480E55F2229BEE6F0031BDF7 /* UIColor-Template.swift in Sources */,
480E568C229C04BD0031BDF7 /* ExampleViewController.swift in Sources */,
+ 488240562349447000CB6FFE /* DataSourceProtocol.swift in Sources */,
480E5692229C05F10031BDF7 /* ExampleTodosWorker.swift in Sources */,
480E55F0229BEE6F0031BDF7 /* UITableView-Template.swift in Sources */,
480E56BD229C14970031BDF7 /* ExampleNavigationRouter.swift in Sources */,
diff --git a/Template/Template/App/Scenes/Example navigation/ExampleNavigationRouter.swift b/Template/Template/App/Scenes/Example navigation/ExampleNavigationRouter.swift
index c598097..b550a91 100644
--- a/Template/Template/App/Scenes/Example navigation/ExampleNavigationRouter.swift
+++ b/Template/Template/App/Scenes/Example navigation/ExampleNavigationRouter.swift
@@ -16,11 +16,11 @@ protocol ExampleNavigationRouterDelegate: class {
func exampleNavigationRouterUnwindBack()
}
-class ExampleNavigationRouter: Router {
- weak var viewController: UIViewController?
+class ExampleNavigationRouter {
+ weak var viewController: ExampleNavigationViewController?
weak var delegate: ExampleNavigationRouterDelegate?
- static func createModule(delegate: ExampleNavigationRouterDelegate?) -> UIViewController {
+ static func createModule(delegate: ExampleNavigationRouterDelegate?) -> ExampleNavigationViewController {
let view = ExampleNavigationViewController()
let interactor = ExampleNavigationInteractor()
let router = ExampleNavigationRouter()
diff --git a/Template/Template/App/Scenes/Example/ExampleRouter.swift b/Template/Template/App/Scenes/Example/ExampleRouter.swift
index be5444b..25199f3 100644
--- a/Template/Template/App/Scenes/Example/ExampleRouter.swift
+++ b/Template/Template/App/Scenes/Example/ExampleRouter.swift
@@ -17,11 +17,11 @@ protocol ExampleRouterDelegate: class {
func exampleRouterRequestedUnwind()
}
-class ExampleRouter: Router {
- weak var viewController: UIViewController?
+class ExampleRouter {
+ weak var viewController: ExampleViewController?
weak var delegate: ExampleRouterDelegate?
- static func createModule(delegate: ExampleRouterDelegate?) -> UIViewController {
+ static func createModule(delegate: ExampleRouterDelegate?) -> ExampleViewController {
let view = ExampleViewController()
let interactor = ExampleInteractor()
let router = ExampleRouter()
@@ -30,7 +30,7 @@ class ExampleRouter: Router {
let presenter = ExamplePresenter(interface: view, interactor: interactor, router: router)
view.presenter = presenter
interactor.presenter = presenter
- return UINavigationController(rootViewController: view)
+ return view
}
}