diff --git a/Cartfile.private b/Cartfile.private index 0244b62..897faf4 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1 +1 @@ -github "Quick/Nimble" ~> 4.1.0 +github "Quick/Nimble" diff --git a/Cartfile.resolved b/Cartfile.resolved index 2353900..0260062 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "Quick/Nimble" "v4.1.0" +github "Quick/Nimble" "220152be528dcc0537764c179c95b8174028c80c" diff --git a/Carthage/Checkouts/Nimble b/Carthage/Checkouts/Nimble index b4a0f9d..220152b 160000 --- a/Carthage/Checkouts/Nimble +++ b/Carthage/Checkouts/Nimble @@ -1 +1 @@ -Subproject commit b4a0f9d6ee6b89f0e2f9ee8fa32aaa7200b1e27c +Subproject commit 220152be528dcc0537764c179c95b8174028c80c diff --git a/Mixer.podspec b/Mixer.podspec index 9196d63..f01e6f1 100644 --- a/Mixer.podspec +++ b/Mixer.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Mixer" - s.version = "0.1.2" + s.version = "0.2" s.summary = "A tiny library helping to centralize color definitions" s.homepage = "https://github.com/ios-studio/Mixer" s.license = { :type => "MIT", :file => "LICENSE" } diff --git a/Mixer.xcodeproj/project.pbxproj b/Mixer.xcodeproj/project.pbxproj index abaaf26..b93b799 100644 --- a/Mixer.xcodeproj/project.pbxproj +++ b/Mixer.xcodeproj/project.pbxproj @@ -357,6 +357,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -400,6 +401,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -424,7 +426,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -444,7 +446,7 @@ PRODUCT_BUNDLE_IDENTIFIER = studio.Mixer; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -459,7 +461,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = studio.MixerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -474,7 +476,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = studio.MixerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/Mixer/CSV.swift b/Mixer/CSV.swift index a090673..dd724da 100644 --- a/Mixer/CSV.swift +++ b/Mixer/CSV.swift @@ -3,8 +3,8 @@ import Foundation internal class CSV { let rows: [[String: String]] - private let headers: [String] - private static let delimiter = NSCharacterSet(charactersInString: ",") + fileprivate let headers: [String] + fileprivate static let delimiter = CharacterSet(charactersIn: ",") init?(contentsOfFile file: String) { let contents: String @@ -16,9 +16,9 @@ internal class CSV { return nil } - let newline = NSCharacterSet.newlineCharacterSet() + let newline = CharacterSet.newlines var lines: [String] = [] - contents.stringByTrimmingCharactersInSet(newline).enumerateLines { line, stop in lines.append(line) + contents.trimmingCharacters(in: newline).enumerateLines { line, stop in lines.append(line) } guard lines.count > 1 else { @@ -27,12 +27,12 @@ internal class CSV { return nil } - let headers = lines[0].componentsSeparatedByCharactersInSet(CSV.delimiter) + let headers = lines[0].components(separatedBy: CSV.delimiter) self.headers = headers self.rows = Array(lines)[1..CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0 CFBundleSignature ???? CFBundleVersion diff --git a/Mixer/Mixer.swift b/Mixer/Mixer.swift index 5e58683..ea70620 100644 --- a/Mixer/Mixer.swift +++ b/Mixer/Mixer.swift @@ -10,7 +10,7 @@ import UIKit Where the columns headers are RGBA channel values and the row headers are the names of the colors. */ -public class Mixer { +open class Mixer { internal struct Color { let red: Int let green: Int @@ -26,27 +26,27 @@ public class Mixer { ) } - private func cgFloatValueOf(value: Int) -> CGFloat { + fileprivate func cgFloatValueOf(_ value: Int) -> CGFloat { return CGFloat(value) / CGFloat(255.0) } } internal typealias Colors = [String: Color] - private let colors: Colors + fileprivate let colors: Colors /** Check if this instance of `Mixer` has colors loaded. Returns `true` if this instance has successfully loaded colors from a file, `false` if not. */ - public var hasColors: Bool { + open var hasColors: Bool { return self.colors.count > 0 } - private static var resourcePaths: [NSBundle: String] = [:] - private static func defaultResourcePathForBundle(bundle: NSBundle) -> String? { + fileprivate static var resourcePaths: [Bundle: String] = [:] + fileprivate static func defaultResourcePathForBundle(_ bundle: Bundle) -> String? { if let path = resourcePaths[bundle] { return path - } else if let path = bundle.pathForResource("Colors", ofType: "csv") { + } else if let path = bundle.path(forResource: "Colors", ofType: "csv") { resourcePaths[bundle] = path return path } @@ -54,7 +54,7 @@ public class Mixer { return nil } - private let configuration: MixerConfiguration + fileprivate let configuration: MixerConfiguration /** Initialize an instance of `Mixer` with a given custom `MixerConfiguration`. Files loaded are cached for the run time of the application so there is no performance penalty in initializing multiple `Mixer` instances. @@ -74,7 +74,7 @@ public class Mixer { - Parameter bundle: The bundle in which to look for the file named `Colors.csv` */ - public convenience init(bundle: NSBundle) { + public convenience init(bundle: Bundle) { guard let path = Mixer.defaultResourcePathForBundle(bundle) else { self.init(configuration: MixerConfiguration(colorDefinitionsPath: "NoPath")) return @@ -88,7 +88,7 @@ public class Mixer { - Parameter name: The color to return */ - public func colorFor(name: String) -> UIColor? { + open func colorFor(_ name: String) -> UIColor? { return colors[name]?.uiColor } @@ -97,8 +97,8 @@ public class Mixer { - Parameter name: The color to return */ - public func colorFor(color: MixerColor) -> UIColor? { + open func colorFor(_ color: MixerColor) -> UIColor? { return colors[color.name]?.uiColor } -} \ No newline at end of file +} diff --git a/Mixer/MixerColorsLoader.swift b/Mixer/MixerColorsLoader.swift index 9dabd2d..aaa8183 100644 --- a/Mixer/MixerColorsLoader.swift +++ b/Mixer/MixerColorsLoader.swift @@ -1,7 +1,7 @@ import UIKit internal class MixerColorsLoader { - private static var cachedPaths: [String: Mixer.Colors] = [:] + fileprivate static var cachedPaths: [String: Mixer.Colors] = [:] let path: String @@ -10,14 +10,14 @@ internal class MixerColorsLoader { } func clear() { - MixerColorsLoader.cachedPaths.removeValueForKey(path) + MixerColorsLoader.cachedPaths.removeValue(forKey: path) } func load() -> Mixer.Colors? { if let cached = MixerColorsLoader.cachedPaths[path] { return cached } - guard let csv = CSV(contentsOfFile: path) where !csv.rows.isEmpty else { + guard let csv = CSV(contentsOfFile: path) , !csv.rows.isEmpty else { logReadFailure("Could not find or read colors csv") return nil } @@ -30,14 +30,14 @@ internal class MixerColorsLoader { return nil } - private func loadColors(csv: CSV) -> Mixer.Colors? { + fileprivate func loadColors(_ csv: CSV) -> Mixer.Colors? { var colors = Mixer.Colors() for row in csv.rows { guard let name = row["Name"], - red = extractColorValue(row, channel: "Red"), - green = extractColorValue(row, channel: "Green"), - blue = extractColorValue(row, channel: "Blue"), - alpha = extractAlphaValue(row) else { + let red = extractColorValue(row, channel: "Red"), + let green = extractColorValue(row, channel: "Green"), + let blue = extractColorValue(row, channel: "Blue"), + let alpha = extractAlphaValue(row) else { return nil } @@ -47,7 +47,7 @@ internal class MixerColorsLoader { return colors } - private func extractColorValue(row: [String: String], channel: String) -> Int? { + fileprivate func extractColorValue(_ row: [String: String], channel: String) -> Int? { guard let string = row[channel] else { logReadFailureForRow(row, message: "Value for \(channel) channel not found") return nil @@ -63,7 +63,7 @@ internal class MixerColorsLoader { return value } - private func extractAlphaValue(row: [String: String]) -> Float? { + fileprivate func extractAlphaValue(_ row: [String: String]) -> Float? { guard let string = row["Alpha"] else { logReadFailureForRow(row, message: "Value for alpha channel not found") return nil @@ -79,19 +79,19 @@ internal class MixerColorsLoader { return value } - private func isValidColorValue(value: Int) -> Bool { + fileprivate func isValidColorValue(_ value: Int) -> Bool { return (0..<256).contains(value) } - private func isValidAlphaValue(value: Float) -> Bool { + fileprivate func isValidAlphaValue(_ value: Float) -> Bool { return (0.0..<1.0).contains(value) || value == 1.0 } - private func logReadFailureForRow(row: [String: String], message: String) { + fileprivate func logReadFailureForRow(_ row: [String: String], message: String) { NSLog("Mixer: Failure parsing color \"\(row["Name"] ?? "")\" - \(message) - colors will not be loaded") } - private func logReadFailure(message: String) { + fileprivate func logReadFailure(_ message: String) { NSLog("Mixer: \(message) - colors will not be loaded") } -} \ No newline at end of file +} diff --git a/MixerTests/CSVTests.swift b/MixerTests/CSVTests.swift index 0e0dd88..55cbec8 100644 --- a/MixerTests/CSVTests.swift +++ b/MixerTests/CSVTests.swift @@ -29,7 +29,7 @@ class CSVTests: XCTestCase { expect(parsed).to(beNil()) } - private func csvPath(fileName: String) -> String { - return NSBundle(forClass: self.dynamicType).pathForResource(fileName, ofType: "csv") ?? "" + fileprivate func csvPath(_ fileName: String) -> String { + return Bundle(for: type(of: self)).path(forResource: fileName, ofType: "csv") ?? "" } } diff --git a/MixerTests/MixerColorsLoaderTests.swift b/MixerTests/MixerColorsLoaderTests.swift index 7e11a2b..2f0cae3 100644 --- a/MixerTests/MixerColorsLoaderTests.swift +++ b/MixerTests/MixerColorsLoaderTests.swift @@ -5,10 +5,10 @@ import Nimble class MixerColorsLoaderTests: XCTestCase { - var fileManager: NSFileManager! + var fileManager: FileManager! override func setUp() { - fileManager = NSFileManager.defaultManager() + fileManager = FileManager.default } override func tearDown() { @@ -17,7 +17,7 @@ class MixerColorsLoaderTests: XCTestCase { func testCache() { let testPath = copyCSVFixtureToTestPath(csvPath("Colors")) - MixerColorsLoader(path: testPath).load() + _ = MixerColorsLoader(path: testPath).load() removeCSVFixtureAtPath(testPath) let cacheLoader = MixerColorsLoader(path: testPath) @@ -32,10 +32,10 @@ class MixerColorsLoaderTests: XCTestCase { expect(deletedResult).to(beNil()) } - private func copyCSVFixtureToTestPath(path: String) -> String { - let newPath = path.stringByReplacingOccurrencesOfString("Colors", withString: "CorrectFontSizes-CacheTest") + fileprivate func copyCSVFixtureToTestPath(_ path: String) -> String { + let newPath = path.replacingOccurrences(of: "Colors", with: "CorrectFontSizes-CacheTest") do { - try fileManager.copyItemAtPath(path, toPath: newPath) + try fileManager.copyItem(atPath: path, toPath: newPath) } catch _ { fail("Could not copy file for cache test") } @@ -43,9 +43,9 @@ class MixerColorsLoaderTests: XCTestCase { return newPath } - private func removeCSVFixtureAtPath(path: String) { + fileprivate func removeCSVFixtureAtPath(_ path: String) { do { - try fileManager.removeItemAtPath(path) + try fileManager.removeItem(atPath: path) } catch _ { fail("Could not remove file for cache test") } @@ -111,7 +111,7 @@ class MixerColorsLoaderTests: XCTestCase { expect(colors).to(beNil()) } - private func csvPath(fileName: String) -> String { - return NSBundle(forClass: self.classForCoder).pathForResource(fileName, ofType: "csv") ?? "" + fileprivate func csvPath(_ fileName: String) -> String { + return Bundle(for: self.classForCoder).path(forResource: fileName, ofType: "csv") ?? "" } } diff --git a/MixerTests/MixerTests.swift b/MixerTests/MixerTests.swift index 5e06a2a..9ee9e82 100644 --- a/MixerTests/MixerTests.swift +++ b/MixerTests/MixerTests.swift @@ -18,7 +18,7 @@ class MixerTests: XCTestCase { continueAfterFailure = false - guard let csvPath = NSBundle(forClass: self.dynamicType).pathForResource("Colors", ofType: "csv") else { + guard let csvPath = Bundle(for: type(of: self)).path(forResource: "Colors", ofType: "csv") else { fail("Color fixture file Colors.csv is missing") return } @@ -34,19 +34,19 @@ class MixerTests: XCTestCase { } func testConvenienceInit() { - let convenienceMixer = Mixer(bundle: NSBundle(forClass: self.dynamicType)) + let convenienceMixer = Mixer(bundle: Bundle(for: type(of: self))) expect(convenienceMixer.hasColors).to(beTrue()) } func testConvenienceInitWithMissingFile() { - let convenienceMixer = Mixer(bundle: NSBundle()) + let convenienceMixer = Mixer(bundle: Bundle()) expect(convenienceMixer.hasColors).to(beFalse()) } func testConvenienceInitPerformance() { - self.measureBlock { + self.measure { for _ in 1..<10000 { - let _ = Mixer(bundle: NSBundle(forClass: self.dynamicType)) + let _ = Mixer(bundle: Bundle(for: type(of: self))) } } } @@ -71,7 +71,7 @@ class MixerTests: XCTestCase { expect(alpha).to(beCloseTo(0.9, within: 0.001)) } - private func extractColorValues(color: UIColor?) -> (CGFloat, CGFloat, CGFloat, CGFloat) { + fileprivate func extractColorValues(_ color: UIColor?) -> (CGFloat, CGFloat, CGFloat, CGFloat) { var red: CGFloat = -1.0 var green: CGFloat = -1.0 var blue: CGFloat = -1.0 diff --git a/README.md b/README.md index 26df779..7039e20 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,18 @@ Centralize your color definitions in a CSV file & easily share them for people t Add the following your Cartfile: ```Swift -github "ios-studio/Mixer" ~> 0.1.2 +github "ios-studio/Mixer" ~> 0.2 ``` #### Via [CocoaPods](https://cocoapods.org/): Add the following your Podfile: ```ruby -pod "Mixer", "~> 0.1.2" +pod "Mixer", "~> 0.2" ``` +Mixer uses Swift 3.0+. For compatibility with Swift 2.3 use version 1.2.1. + ## Default Setup Mixer will look for a file named `Colors.csv` in the specified bundle or at the specified path. [The contents of the file should look like this](https://github.com/ios-studio/Mixer/blob/master/MixerTests/Support/Colors.csv). It is important to keep the headers as shown, otherwise Mixer will not be able to read the file. @@ -42,7 +44,7 @@ Mixer can be passed a `MixerConfiguration` object where you can specify another Pass the bundle to initialize. Mixer will look up the `Colors` file in the bundle and cache it for subsequent initializations in the same process: ```Swift -let bundle = NSBundle(forClass: self.dynamicType) +let bundle = Bundle(for: type(of: self) let mixer = Mixer(bundle: bundle) ```