diff --git a/OpenSourceController.xcodeproj/project.pbxproj b/OpenSourceController.xcodeproj/project.pbxproj index d669742..d5c962e 100644 --- a/OpenSourceController.xcodeproj/project.pbxproj +++ b/OpenSourceController.xcodeproj/project.pbxproj @@ -8,8 +8,6 @@ /* Begin PBXBuildFile section */ 52D6D9871BEFF229002C0205 /* OpenSourceController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* OpenSourceController.framework */; }; - 76229B6E2180AD6400A61697 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76229B6C2180AD6400A61697 /* UIViewController+Extensions.swift */; }; - 76229B6F2180AD6400A61697 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76229B6D2180AD6400A61697 /* UIView+Extensions.swift */; }; 76229B722180AD8400A61697 /* LicenceLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76229B712180AD8400A61697 /* LicenceLoader.swift */; }; 76229B7D2180AD9F00A61697 /* HTTPDataLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76229B7C2180AD9F00A61697 /* HTTPDataLoader.swift */; }; 76229B802180ADA800A61697 /* OpenSourceControllerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76229B7E2180ADA800A61697 /* OpenSourceControllerConfig.swift */; }; @@ -18,7 +16,11 @@ 769FD9D221871DEC00FB5A53 /* LicenceListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 769FD9CE21871DEC00FB5A53 /* LicenceListViewController.swift */; }; 769FD9D321871DEC00FB5A53 /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 769FD9CF21871DEC00FB5A53 /* LoadingViewController.swift */; }; 769FD9D421871DEC00FB5A53 /* OpenSourceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 769FD9D021871DEC00FB5A53 /* OpenSourceTableViewCell.swift */; }; - 76EAA8481E93EDB3009A41DA /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76EAA8471E93EDB3009A41DA /* Array+Extensions.swift */; }; + 76D7F24521BEB18A004B74CB /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D7F24021BEB18A004B74CB /* UITableView+Extensions.swift */; }; + 76D7F24621BEB18A004B74CB /* Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D7F24121BEB18A004B74CB /* Reusable.swift */; }; + 76D7F24721BEB18A004B74CB /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D7F24221BEB18A004B74CB /* UIViewController+Extensions.swift */; }; + 76D7F24821BEB18A004B74CB /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D7F24321BEB18A004B74CB /* Array+Extensions.swift */; }; + 76D7F24921BEB18A004B74CB /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76D7F24421BEB18A004B74CB /* UIView+Extensions.swift */; }; 76EAA84F1E93EDCD009A41DA /* LicenceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76EAA84C1E93EDCD009A41DA /* LicenceFile.swift */; }; /* End PBXBuildFile section */ @@ -35,8 +37,6 @@ /* Begin PBXFileReference section */ 52D6D97C1BEFF229002C0205 /* OpenSourceController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenSourceController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52D6D9861BEFF229002C0205 /* OpenSourceController-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OpenSourceController-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 76229B6C2180AD6400A61697 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIViewController+Extensions.swift"; path = "Sources/Extensions/UIViewController+Extensions.swift"; sourceTree = ""; }; - 76229B6D2180AD6400A61697 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Extensions.swift"; path = "Sources/Extensions/UIView+Extensions.swift"; sourceTree = ""; }; 76229B712180AD8400A61697 /* LicenceLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LicenceLoader.swift; path = Sources/Model/LicenceLoader.swift; sourceTree = ""; }; 76229B7C2180AD9F00A61697 /* HTTPDataLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTTPDataLoader.swift; path = Sources/Loader/HTTPDataLoader.swift; sourceTree = ""; }; 76229B7E2180ADA800A61697 /* OpenSourceControllerConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenSourceControllerConfig.swift; path = Sources/OpenSourceControllerConfig.swift; sourceTree = ""; }; @@ -45,7 +45,11 @@ 769FD9CE21871DEC00FB5A53 /* LicenceListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LicenceListViewController.swift; path = Sources/Controller/LicenceListViewController.swift; sourceTree = ""; }; 769FD9CF21871DEC00FB5A53 /* LoadingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadingViewController.swift; path = Sources/Controller/LoadingViewController.swift; sourceTree = ""; }; 769FD9D021871DEC00FB5A53 /* OpenSourceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenSourceTableViewCell.swift; path = Sources/Controller/OpenSourceTableViewCell.swift; sourceTree = ""; }; - 76EAA8471E93EDB3009A41DA /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Array+Extensions.swift"; path = "Sources/Extensions/Array+Extensions.swift"; sourceTree = ""; }; + 76D7F24021BEB18A004B74CB /* UITableView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UITableView+Extensions.swift"; path = "Sources/Utils/UITableView+Extensions.swift"; sourceTree = ""; }; + 76D7F24121BEB18A004B74CB /* Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Reusable.swift; path = Sources/Utils/Reusable.swift; sourceTree = ""; }; + 76D7F24221BEB18A004B74CB /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIViewController+Extensions.swift"; path = "Sources/Utils/UIViewController+Extensions.swift"; sourceTree = ""; }; + 76D7F24321BEB18A004B74CB /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Array+Extensions.swift"; path = "Sources/Utils/Array+Extensions.swift"; sourceTree = ""; }; + 76D7F24421BEB18A004B74CB /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Extensions.swift"; path = "Sources/Utils/UIView+Extensions.swift"; sourceTree = ""; }; 76EAA84C1E93EDCD009A41DA /* LicenceFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LicenceFile.swift; path = Sources/Model/LicenceFile.swift; sourceTree = ""; }; AD2FAA261CD0B6D800659CF4 /* OpenSourceController.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = OpenSourceController.plist; sourceTree = ""; }; AD2FAA281CD0B6E100659CF4 /* OpenSourceControllerTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = OpenSourceControllerTests.plist; sourceTree = ""; }; @@ -114,14 +118,16 @@ name = Loader; sourceTree = ""; }; - 76EAA8491E93EDBB009A41DA /* Extensions */ = { + 76EAA8491E93EDBB009A41DA /* Utils */ = { isa = PBXGroup; children = ( - 76229B6D2180AD6400A61697 /* UIView+Extensions.swift */, - 76229B6C2180AD6400A61697 /* UIViewController+Extensions.swift */, - 76EAA8471E93EDB3009A41DA /* Array+Extensions.swift */, + 76D7F24321BEB18A004B74CB /* Array+Extensions.swift */, + 76D7F24121BEB18A004B74CB /* Reusable.swift */, + 76D7F24021BEB18A004B74CB /* UITableView+Extensions.swift */, + 76D7F24421BEB18A004B74CB /* UIView+Extensions.swift */, + 76D7F24221BEB18A004B74CB /* UIViewController+Extensions.swift */, ); - name = Extensions; + name = Utils; sourceTree = ""; }; 76EAA84A1E93EDC0009A41DA /* Sources */ = { @@ -132,7 +138,7 @@ 76229B7B2180AD8E00A61697 /* Loader */, 76229B702180AD7700A61697 /* Model */, 76EAA8511E93EDD2009A41DA /* Controller */, - 76EAA8491E93EDBB009A41DA /* Extensions */, + 76EAA8491E93EDBB009A41DA /* Utils */, ); name = Sources; sourceTree = ""; @@ -276,18 +282,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 76D7F24921BEB18A004B74CB /* UIView+Extensions.swift in Sources */, 76229B7D2180AD9F00A61697 /* HTTPDataLoader.swift in Sources */, - 76229B6F2180AD6400A61697 /* UIView+Extensions.swift in Sources */, + 76D7F24621BEB18A004B74CB /* Reusable.swift in Sources */, 769FD9D221871DEC00FB5A53 /* LicenceListViewController.swift in Sources */, 769FD9D121871DEC00FB5A53 /* OpenSourceViewController.swift in Sources */, + 76D7F24721BEB18A004B74CB /* UIViewController+Extensions.swift in Sources */, 76EAA84F1E93EDCD009A41DA /* LicenceFile.swift in Sources */, 76229B722180AD8400A61697 /* LicenceLoader.swift in Sources */, + 76D7F24521BEB18A004B74CB /* UITableView+Extensions.swift in Sources */, 769FD9D421871DEC00FB5A53 /* OpenSourceTableViewCell.swift in Sources */, + 76D7F24821BEB18A004B74CB /* Array+Extensions.swift in Sources */, 76229B812180ADA800A61697 /* OpenSourceController.swift in Sources */, - 76229B6E2180AD6400A61697 /* UIViewController+Extensions.swift in Sources */, 769FD9D321871DEC00FB5A53 /* LoadingViewController.swift in Sources */, 76229B802180ADA800A61697 /* OpenSourceControllerConfig.swift in Sources */, - 76EAA8481E93EDB3009A41DA /* Array+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate b/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate index f26f3a4..38ec9e3 100644 Binary files a/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate and b/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Sources/Controller/LicenceListViewController.swift b/Sources/Controller/LicenceListViewController.swift index e5c80e9..cd8fe2e 100644 --- a/Sources/Controller/LicenceListViewController.swift +++ b/Sources/Controller/LicenceListViewController.swift @@ -11,8 +11,6 @@ import UIKit final class LicenceListViewController: UITableViewController { // MARK: - Var - - fileprivate let reuseIdentifier = "openSourceCell" fileprivate var config: OpenSourceControllerConfig @@ -40,7 +38,7 @@ final class LicenceListViewController: UITableViewController { fileprivate func prepareTableView() { self.tableView.tableFooterView = UIView() - self.tableView.register(OpenSourceTableViewCell.self, forCellReuseIdentifier: self.reuseIdentifier) + self.tableView.register(cellType: OpenSourceTableViewCell.self) self.tableView.dataSource = self self.tableView.delegate = self self.tableView.separatorStyle = .singleLine @@ -61,19 +59,10 @@ extension LicenceListViewController { } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - var cell = tableView.dequeueReusableCell(withIdentifier: self.reuseIdentifier, - for: indexPath) as? OpenSourceTableViewCell - // Init cell - if cell == nil { - cell = OpenSourceTableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: self.reuseIdentifier) - } - - // Configure the cell with licence - if let licence = self.downloadedLicence.get(at: indexPath.row) { - cell?.configure(licence: licence, config: self.config) - } - - return cell! + let cell: OpenSourceTableViewCell = tableView.dequeueReusableCell(for: indexPath) + guard let licence = self.downloadedLicence.get(at: indexPath.row) else { return cell } + cell.configure(licence: licence, config: self.config) + return cell } override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { diff --git a/Sources/Controller/OpenSourceTableViewCell.swift b/Sources/Controller/OpenSourceTableViewCell.swift index 77a6d6d..ebad072 100644 --- a/Sources/Controller/OpenSourceTableViewCell.swift +++ b/Sources/Controller/OpenSourceTableViewCell.swift @@ -6,7 +6,7 @@ import UIKit -final class OpenSourceTableViewCell: UITableViewCell { +final class OpenSourceTableViewCell: UITableViewCell, Reusable { // MARK: - Lifecycle @@ -29,15 +29,10 @@ final class OpenSourceTableViewCell: UITableViewCell { // MARK: - Configure - /// Initialize the cell content with Licence model - /// - /// - Parameter licence: the licence model func configure(licence: LicenceFile, config: OpenSourceControllerConfig) { - // Set text self.textLabel?.attributedText = licence.attributedContent self.textLabel?.textColor = config.uiConfig.licenceTextColor - // Background if let backgroundColor = config.uiConfig.licenceBackgroundColor { self.backgroundColor = backgroundColor } diff --git a/Sources/Controller/OpenSourceViewController.swift b/Sources/Controller/OpenSourceViewController.swift index 6789ca4..2908d4a 100644 --- a/Sources/Controller/OpenSourceViewController.swift +++ b/Sources/Controller/OpenSourceViewController.swift @@ -14,6 +14,8 @@ final class OpenSourceViewController: UIViewController { fileprivate var licences: [LicenceFile] + fileprivate var licenceLoader: LicenceLoader + fileprivate var config: OpenSourceControllerConfig fileprivate lazy var loadingController = { @@ -28,7 +30,8 @@ final class OpenSourceViewController: UIViewController { // MARK: - Lifecyle - init(licences: [LicenceFile], showCloseButton: Bool, configuration: OpenSourceControllerConfig) { + init(licences: [LicenceFile], showCloseButton: Bool, configuration: OpenSourceControllerConfig, licenceLoader: LicenceLoader) { + self.licenceLoader = licenceLoader self.licences = licences self.showCloseButton = showCloseButton self.config = configuration @@ -56,12 +59,10 @@ final class OpenSourceViewController: UIViewController { // MARK: - Prepare fileprivate func prepareStyle() { - // Apply navigation bar tint color if needed if let tintColor = self.config.uiConfig.barTintColor { self.navigationController?.navigationBar.barTintColor = tintColor } - // Apply navigation bar text color if needed if let textColor = self.config.uiConfig.titleColor { let attribut = [NSAttributedString.Key.foregroundColor: textColor] self.navigationController?.navigationBar.titleTextAttributes = attribut @@ -69,7 +70,7 @@ final class OpenSourceViewController: UIViewController { } fileprivate func prepareLicences() { - LicenceLoader.downloadLicences(licences: licences, config: config) { [weak self] in + self.licenceLoader.downloadLicences(licences: licences, config: config) { [weak self] in guard let strongSelf = self else { return } let listController = LicenceListViewController(downloadedLicence: strongSelf.licences, config: strongSelf.config) strongSelf.loadingController.remove() diff --git a/Sources/Model/LicenceLoader.swift b/Sources/Model/LicenceLoader.swift index d61a2ef..ce24bfd 100644 --- a/Sources/Model/LicenceLoader.swift +++ b/Sources/Model/LicenceLoader.swift @@ -13,7 +13,7 @@ final class LicenceLoader { /// - Parameters: /// - licences: array which contains licence model model /// - completion: end downloading completion - class func downloadLicences(licences: [LicenceFile], + func downloadLicences(licences: [LicenceFile], config: OpenSourceControllerConfig, completion: @escaping () -> Void) { let licenceGroupe = DispatchGroup() diff --git a/Sources/OpenSourceController.swift b/Sources/OpenSourceController.swift index 8f9c414..4084352 100644 --- a/Sources/OpenSourceController.swift +++ b/Sources/OpenSourceController.swift @@ -18,7 +18,11 @@ open class OpenSourceController: NSObject { /// /// - Parameter from: the source controller open func presentOpenSourceController(from: UIViewController) { - let licenceController = OpenSourceViewController(licences: licences, showCloseButton: true, configuration: config) + let loader: LicenceLoader = LicenceLoader() + let licenceController = OpenSourceViewController(licences: licences, + showCloseButton: true, + configuration: config, + licenceLoader: loader) let navController = UINavigationController(rootViewController: licenceController) from.present(navController, animated: true) } @@ -27,7 +31,11 @@ open class OpenSourceController: NSObject { /// /// - Parameter from: the source controller open func pushOpenSourceController(from: UIViewController) { - let licenceController = OpenSourceViewController(licences: licences, showCloseButton: false, configuration: config) + let loader: LicenceLoader = LicenceLoader() + let licenceController = OpenSourceViewController(licences: licences, + showCloseButton: false, + configuration: config, + licenceLoader: loader) guard let navigationController = from.navigationController else { assertionFailure("Source controller isn't embeded in navigation controller. Can't push.") return diff --git a/Sources/Extensions/Array+Extensions.swift b/Sources/Utils/Array+Extensions.swift similarity index 100% rename from Sources/Extensions/Array+Extensions.swift rename to Sources/Utils/Array+Extensions.swift diff --git a/Sources/Utils/Reusable.swift b/Sources/Utils/Reusable.swift new file mode 100644 index 0000000..c1b6086 --- /dev/null +++ b/Sources/Utils/Reusable.swift @@ -0,0 +1,19 @@ +// +// Reusable.swift +// OpenSourceControllerDemo +// +// Created by Florian Gabach on 10/12/2018. +// Copyright © 2018 OpenSourceController. All rights reserved. +// + +import Foundation + +public protocol Reusable: class { + static var reuseIdentifier: String { get } +} + +public extension Reusable { + static var reuseIdentifier: String { + return String(describing: self) + } +} diff --git a/Sources/Utils/UITableView+Extensions.swift b/Sources/Utils/UITableView+Extensions.swift new file mode 100644 index 0000000..44fbe4c --- /dev/null +++ b/Sources/Utils/UITableView+Extensions.swift @@ -0,0 +1,28 @@ +// +// UITableView+Extensions.swift +// OpenSourceControllerDemo +// +// Created by Florian Gabach on 10/12/2018. +// Copyright © 2018 OpenSourceController. All rights reserved. +// + +import UIKit + +extension UITableView { + final func register(cellType: T.Type) + where T: Reusable { + self.register(cellType.self, forCellReuseIdentifier: cellType.reuseIdentifier) + } + + final func dequeueReusableCell(for indexPath: IndexPath, cellType: T.Type = T.self) -> T + where T: Reusable { + guard let cell = self.dequeueReusableCell(withIdentifier: cellType.reuseIdentifier, for: indexPath) as? T else { + fatalError( + "Failed to dequeue a cell with identifier \(cellType.reuseIdentifier) matching type \(cellType.self). " + + "Check that the reuseIdentifier is set properly in your XIB/Storyboard " + + "and that you registered the cell beforehand" + ) + } + return cell + } +} diff --git a/Sources/Extensions/UIView+Extensions.swift b/Sources/Utils/UIView+Extensions.swift similarity index 100% rename from Sources/Extensions/UIView+Extensions.swift rename to Sources/Utils/UIView+Extensions.swift diff --git a/Sources/Extensions/UIViewController+Extensions.swift b/Sources/Utils/UIViewController+Extensions.swift similarity index 100% rename from Sources/Extensions/UIViewController+Extensions.swift rename to Sources/Utils/UIViewController+Extensions.swift