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 } }