commit 9e9bf56fba505a48ee900cbc6decff6325db79e8 Author: Florian Gabach Date: Mon Feb 27 17:07:34 2017 +0100 First commit diff --git a/OpenSourceController/OpenSourceController.xcodeproj/project.pbxproj b/OpenSourceController/OpenSourceController.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7aeff44 --- /dev/null +++ b/OpenSourceController/OpenSourceController.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 7608FF731E6485A700656BA2 /* OpenSourceController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7608FF711E6485A700656BA2 /* OpenSourceController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7608FF7E1E6485D000656BA2 /* LicenceDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7608FF7C1E6485D000656BA2 /* LicenceDownloader.swift */; }; + 7608FF7F1E6485D000656BA2 /* LicenceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7608FF7D1E6485D000656BA2 /* LicenceFile.swift */; }; + 7608FF811E6485D600656BA2 /* OpenSourceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7608FF801E6485D600656BA2 /* OpenSourceTableViewCell.swift */; }; + 7608FF841E6485DE00656BA2 /* OpenSourceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7608FF821E6485DE00656BA2 /* OpenSourceController.swift */; }; + 7608FF851E6485DE00656BA2 /* OpenSourceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7608FF831E6485DE00656BA2 /* OpenSourceViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7608FF6E1E6485A700656BA2 /* OpenSourceController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenSourceController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7608FF711E6485A700656BA2 /* OpenSourceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenSourceController.h; sourceTree = ""; }; + 7608FF721E6485A700656BA2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7608FF7C1E6485D000656BA2 /* LicenceDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LicenceDownloader.swift; path = Source/Model/LicenceDownloader.swift; sourceTree = SOURCE_ROOT; }; + 7608FF7D1E6485D000656BA2 /* LicenceFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LicenceFile.swift; path = Source/Model/LicenceFile.swift; sourceTree = SOURCE_ROOT; }; + 7608FF801E6485D600656BA2 /* OpenSourceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenSourceTableViewCell.swift; path = Source/View/OpenSourceTableViewCell.swift; sourceTree = SOURCE_ROOT; }; + 7608FF821E6485DE00656BA2 /* OpenSourceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenSourceController.swift; path = Source/Controller/OpenSourceController.swift; sourceTree = SOURCE_ROOT; }; + 7608FF831E6485DE00656BA2 /* OpenSourceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenSourceViewController.swift; path = Source/Controller/OpenSourceViewController.swift; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7608FF6A1E6485A700656BA2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7608FF641E6485A700656BA2 = { + isa = PBXGroup; + children = ( + 7608FF701E6485A700656BA2 /* OpenSourceController */, + 7608FF6F1E6485A700656BA2 /* Products */, + ); + sourceTree = ""; + }; + 7608FF6F1E6485A700656BA2 /* Products */ = { + isa = PBXGroup; + children = ( + 7608FF6E1E6485A700656BA2 /* OpenSourceController.framework */, + ); + name = Products; + sourceTree = ""; + }; + 7608FF701E6485A700656BA2 /* OpenSourceController */ = { + isa = PBXGroup; + children = ( + 7608FF7B1E6485C400656BA2 /* Controller */, + 7608FF7A1E6485BE00656BA2 /* View */, + 7608FF791E6485BA00656BA2 /* Model */, + 7608FF711E6485A700656BA2 /* OpenSourceController.h */, + 7608FF721E6485A700656BA2 /* Info.plist */, + ); + path = OpenSourceController; + sourceTree = ""; + }; + 7608FF791E6485BA00656BA2 /* Model */ = { + isa = PBXGroup; + children = ( + 7608FF7C1E6485D000656BA2 /* LicenceDownloader.swift */, + 7608FF7D1E6485D000656BA2 /* LicenceFile.swift */, + ); + name = Model; + sourceTree = ""; + }; + 7608FF7A1E6485BE00656BA2 /* View */ = { + isa = PBXGroup; + children = ( + 7608FF801E6485D600656BA2 /* OpenSourceTableViewCell.swift */, + ); + name = View; + sourceTree = ""; + }; + 7608FF7B1E6485C400656BA2 /* Controller */ = { + isa = PBXGroup; + children = ( + 7608FF821E6485DE00656BA2 /* OpenSourceController.swift */, + 7608FF831E6485DE00656BA2 /* OpenSourceViewController.swift */, + ); + name = Controller; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 7608FF6B1E6485A700656BA2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7608FF731E6485A700656BA2 /* OpenSourceController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 7608FF6D1E6485A700656BA2 /* OpenSourceController */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7608FF761E6485A700656BA2 /* Build configuration list for PBXNativeTarget "OpenSourceController" */; + buildPhases = ( + 7608FF691E6485A700656BA2 /* Sources */, + 7608FF6A1E6485A700656BA2 /* Frameworks */, + 7608FF6B1E6485A700656BA2 /* Headers */, + 7608FF6C1E6485A700656BA2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OpenSourceController; + productName = OpenSourceController; + productReference = 7608FF6E1E6485A700656BA2 /* OpenSourceController.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7608FF651E6485A700656BA2 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0820; + ORGANIZATIONNAME = "Florian Gabach"; + TargetAttributes = { + 7608FF6D1E6485A700656BA2 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = 62PP362QNQ; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 7608FF681E6485A700656BA2 /* Build configuration list for PBXProject "OpenSourceController" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7608FF641E6485A700656BA2; + productRefGroup = 7608FF6F1E6485A700656BA2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7608FF6D1E6485A700656BA2 /* OpenSourceController */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7608FF6C1E6485A700656BA2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7608FF691E6485A700656BA2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7608FF851E6485DE00656BA2 /* OpenSourceViewController.swift in Sources */, + 7608FF841E6485DE00656BA2 /* OpenSourceController.swift in Sources */, + 7608FF811E6485D600656BA2 /* OpenSourceTableViewCell.swift in Sources */, + 7608FF7E1E6485D000656BA2 /* LicenceDownloader.swift in Sources */, + 7608FF7F1E6485D000656BA2 /* LicenceFile.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7608FF741E6485A700656BA2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7608FF751E6485A700656BA2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 7608FF771E6485A700656BA2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 62PP362QNQ; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = OpenSourceController/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.fg.OpenSourceController; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 7608FF781E6485A700656BA2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 62PP362QNQ; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = OpenSourceController/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.fg.OpenSourceController; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7608FF681E6485A700656BA2 /* Build configuration list for PBXProject "OpenSourceController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7608FF741E6485A700656BA2 /* Debug */, + 7608FF751E6485A700656BA2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7608FF761E6485A700656BA2 /* Build configuration list for PBXNativeTarget "OpenSourceController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7608FF771E6485A700656BA2 /* Debug */, + 7608FF781E6485A700656BA2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7608FF651E6485A700656BA2 /* Project object */; +} diff --git a/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..f0ab45b --- /dev/null +++ b/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate b/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..a45211a Binary files /dev/null and b/OpenSourceController/OpenSourceController.xcodeproj/project.xcworkspace/xcuserdata/floriangabach.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/OpenSourceController/OpenSourceController.xcodeproj/xcshareddata/xcschemes/OpenSourceController.xcscheme b/OpenSourceController/OpenSourceController.xcodeproj/xcshareddata/xcschemes/OpenSourceController.xcscheme new file mode 100644 index 0000000..fc48e27 --- /dev/null +++ b/OpenSourceController/OpenSourceController.xcodeproj/xcshareddata/xcschemes/OpenSourceController.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenSourceController/OpenSourceController.xcodeproj/xcuserdata/floriangabach.xcuserdatad/xcschemes/xcschememanagement.plist b/OpenSourceController/OpenSourceController.xcodeproj/xcuserdata/floriangabach.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..3ff9f57 --- /dev/null +++ b/OpenSourceController/OpenSourceController.xcodeproj/xcuserdata/floriangabach.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + OpenSourceController.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + 7608FF6D1E6485A700656BA2 + + primary + + + + + diff --git a/OpenSourceController/OpenSourceController/OpenSourceController.h b/OpenSourceController/OpenSourceController/OpenSourceController.h new file mode 100644 index 0000000..83e04dd --- /dev/null +++ b/OpenSourceController/OpenSourceController/OpenSourceController.h @@ -0,0 +1,19 @@ +// +// OpenSourceController.h +// OpenSourceController +// +// Created by Florian Gabach on 27/02/2017. +// Copyright © 2017 Florian Gabach. All rights reserved. +// + +#import + +//! Project version number for OpenSourceController. +FOUNDATION_EXPORT double OpenSourceControllerVersionNumber; + +//! Project version string for OpenSourceController. +FOUNDATION_EXPORT const unsigned char OpenSourceControllerVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/OpenSourceController/Source/Controller/OpenSourceController.swift b/OpenSourceController/Source/Controller/OpenSourceController.swift new file mode 100644 index 0000000..efcb9cf --- /dev/null +++ b/OpenSourceController/Source/Controller/OpenSourceController.swift @@ -0,0 +1,32 @@ +// +// OpenSourceController.swift +// Pods +// +// Created by Florian Gabach on 05/02/2017. +// +// + +import UIKit + +public class OpenSourceController: NSObject { + + // Contains list of licence object + public var licences: [LicenceFile]? + + /// Present OpenSourceViewController embbeded in navigation controller + /// + /// - Parameter from: the source controller + public final func presentOpenSourceController(from: UIViewController) { + // Create open source controller + let licenceController = OpenSourceViewController() + + // Init licence + licenceController.licences = self.licences + + // Embed in navigation controller + let navController = UINavigationController(rootViewController: licenceController) + + // Present controller + from.present(navController, animated: true) + } +} diff --git a/OpenSourceController/Source/Controller/OpenSourceViewController.swift b/OpenSourceController/Source/Controller/OpenSourceViewController.swift new file mode 100644 index 0000000..3c36f86 --- /dev/null +++ b/OpenSourceController/Source/Controller/OpenSourceViewController.swift @@ -0,0 +1,158 @@ +// +// OpenSourceViewController.swift +// Pods +// +// Created by Florian Gabach on 05/02/2017. +// +// + +import UIKit + +class OpenSourceViewController: UITableViewController { + + // MARK: - Var + + /// Loading indicator + fileprivate var indicator = UIActivityIndicatorView() + + /// TableViewCell identifier + private let reuseIdentifier = "openSourceCell" + + /// Contains all licence object before downloaded + var licences: [LicenceFile]? + + /// Contains all licences object after downloaded + fileprivate var downloadedLicence: [LicenceFile]? { + didSet { + // Update UI + DispatchQueue.main.async { + self.stopLoading() + self.tableView.reloadData() + } + } + } + + // MARK: - Lifecyle + + override func viewDidLoad() { + super.viewDidLoad() + + // Prepare tableview + self.prepareTableView() + + // Download licences + self.prepareLicences() + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + + // MARK: - Prepare + + /// Download licences + fileprivate func prepareLicences() { + if let licences = self.licences { + self.startLoading() + LicenceDownloader.downloadLicences(licences: licences) { () in + // Update licences + self.downloadedLicence = self.licences + } + } + } + + /// Init tableView dataSource, delegate, bar button & title + fileprivate func prepareTableView() { + // Common init + self.tableView.tableFooterView = UIView() + self.title = NSLocalizedString("Tiers library", comment: "") + self.tableView.register(OpenSourceTableViewCell.self, forCellReuseIdentifier: self.reuseIdentifier) + self.tableView.dataSource = self + self.tableView.delegate = self + self.tableView.separatorStyle = .singleLine + + // Close button (on the right corner of navigation bar) + let closeButton = UIBarButtonItem(barButtonSystemItem: .stop, + target: self, + action: #selector(self.closePicker)) + self.navigationItem.rightBarButtonItem = closeButton + + // Loading indicator + self.prepareActivityIndicator() + } + + // MARK: - Loading indicator + + /// Prepare UIActivityIndicatorView and display it at the center of the view + fileprivate func prepareActivityIndicator() { + self.indicator = UIActivityIndicatorView(frame:CGRect(x: 0, y: 0, width: 40, height: 40) ) + self.indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray + self.indicator.center = self.view.center + self.view.addSubview(indicator) + } + + /// Start loading : start the loader animation + fileprivate func startLoading() { + self.indicator.startAnimating() + self.indicator.backgroundColor = UIColor.clear + self.indicator.color = UIColor.black + self.indicator.isHidden = false + } + + /// Stop loading : stop and hide the loader + fileprivate func stopLoading() { + self.indicator.hidesWhenStopped = true + self.indicator.stopAnimating() + self.indicator.isHidden = true + } + + // MARK: - Table View Data Source + + override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return self.downloadedLicence?.count ?? 0 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + var cell = tableView.dequeueReusableCell(withIdentifier: self.reuseIdentifier, + for: indexPath) as? OpenSourceTableViewCell + if cell == nil { + cell = OpenSourceTableViewCell(style: UITableViewCellStyle.default, + reuseIdentifier: self.reuseIdentifier) + } + + let libraryTitleAttribut = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: UIFont.systemFontSize + 2)] + let libraryLicenceAttribut = [NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.systemFontSize)] + let libraryTitle = NSMutableAttributedString(string: self.downloadedLicence?[indexPath.row].title ?? "", + attributes: libraryTitleAttribut) + libraryTitle.append(NSAttributedString(string: "\n\n")) + libraryTitle.append(NSAttributedString(string: self.downloadedLicence?[indexPath.row].detail ?? "", + attributes: libraryLicenceAttribut)) + cell?.textLabel?.attributedText = libraryTitle + + return cell! + } + + override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableViewAutomaticDimension + } + + // MARK: - Action + + /// Handler for click on close button + @objc fileprivate func closePicker() { + self.dismissController() + } + + // MARK: - Navigation + + /// Dismiss the OpenSourceController + func dismissController() { + DispatchQueue.main.async { + self.dismiss(animated: true, completion: nil) + } + } +} diff --git a/OpenSourceController/Source/Model/LicenceDownloader.swift b/OpenSourceController/Source/Model/LicenceDownloader.swift new file mode 100644 index 0000000..faf8264 --- /dev/null +++ b/OpenSourceController/Source/Model/LicenceDownloader.swift @@ -0,0 +1,38 @@ +// +// LicenceDownloader.swift +// Pods +// +// Created by Florian Gabach on 21/02/2017. +// +// + +import UIKit + +class LicenceDownloader: NSObject { + + /// Download every licence + /// + /// - Parameters: + /// - licences: array which contains licence model model + /// - completion: end downloading completion + class func downloadLicences(licences: [LicenceFile], + completion: @escaping () -> Void) { + // Number of licences + let licenceCount = licences.count + + // Already licence downloaded + var alreadyDownloaded = 0 + + // Download licence's detail for every lience + for licence in licences { + licence.downloadLicenceDetail(completion: { () in + alreadyDownloaded += 1 + + // If this is the last licence, perfom completion + if licenceCount == alreadyDownloaded { + completion() + } + }) + } + } +} diff --git a/OpenSourceController/Source/Model/LicenceFile.swift b/OpenSourceController/Source/Model/LicenceFile.swift new file mode 100644 index 0000000..d77567f --- /dev/null +++ b/OpenSourceController/Source/Model/LicenceFile.swift @@ -0,0 +1,56 @@ +// +// LicenceFile.swift +// Pods +// +// Created by Florian Gabach on 05/02/2017. +// +// + +import UIKit + +public class LicenceFile: NSObject { + + // MARK- Var + + /// Name of the library + var title: String? + + /// Url of the library's licence + var url: String + + /// Library's licence + var detail: String? + + // MARK- Init + + /// Licence initializer + /// + /// - Parameters: + /// - title: name of the library + /// - url: url of the licence content + public init(title: String, url: String) { + self.title = title + self.url = url + } + + /// Download licence detail + /// + /// - Parameter completion: end of download handler + func downloadLicenceDetail(completion: @escaping (Void) -> Void) { + if let url = URL(string: self.url) { + let task = URLSession.shared.dataTask(with: url) { (data, _, _) in + if let data = data, + let html = String(data: data, encoding: String.Encoding.utf8) { + + // Update licence model + self.detail = html + + // Log + print("Licence for \(self.title ?? "") downloaded with success.") + } + completion() + } + task.resume() + } + } +} diff --git a/OpenSourceController/Source/View/OpenSourceTableViewCell.swift b/OpenSourceController/Source/View/OpenSourceTableViewCell.swift new file mode 100644 index 0000000..cd6cc7a --- /dev/null +++ b/OpenSourceController/Source/View/OpenSourceTableViewCell.swift @@ -0,0 +1,63 @@ +// +// OpenSourceTableViewCell.swift +// Pods +// +// Created by Florian Gabach on 05/02/2017. +// +// + +import UIKit + +class OpenSourceTableViewCell: UITableViewCell { + + // MARK: IBOutlet + + @IBOutlet var licenceTitle: UILabel! + @IBOutlet var licenceDesc: UILabel! + + // MARK: - Lifecycle + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: .default, + reuseIdentifier: reuseIdentifier) + + self.prepareCellComponent() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + } + + override func layoutSubviews() { + super.layoutSubviews() + } + + // MARK: - Prepare + + func prepareCellComponent() { + // Text + self.textLabel?.numberOfLines = 0 + + // Common init + self.accessoryType = .none + self.selectionStyle = .none + } + + // MARK: - Configure + + /// Initialize the cell content with Licence model + /// + /// - Parameter licence: the licence model + func configure(licence: LicenceFile) { + + // Library's name + self.licenceTitle.text = licence.title + + // Library licence's detail + self.licenceDesc.text = licence.detail + } +}