diff --git a/CHANGELOG.md b/CHANGELOG.md index a0db20f83..56d186379 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,10 @@ [426](https://github.com/SwiftGen/SwiftGen/issues/426) [468](https://github.com/SwiftGen/SwiftGen/issues/468) [573](https://github.com/SwiftGen/SwiftGen/pull/573) +* Assets: there's a new template called `simple-swift4` which removes the need for the last call part like `.color` or `.image`. Also it adds a typealias for each catalog if multiple are used to prevent calls like `Asset.Colors` or `Asset.Images`. For more information, check the [template's documentation](Documentation/templates/xcassets/simple-swift4.md). + [Cihat Gündüz](https://github.com/Dschee) + [603](https://github.com/SwiftGen/SwiftGen/issues/603) + [605](https://github.com/SwiftGen/SwiftGen/pull/605) ### Bug Fixes diff --git a/Documentation/templates/xcassets/simple-swift4.md b/Documentation/templates/xcassets/simple-swift4.md new file mode 100644 index 000000000..f483ce118 --- /dev/null +++ b/Documentation/templates/xcassets/simple-swift4.md @@ -0,0 +1,71 @@ +## Template Information + +| Name | Description | +| --------- | ----------------- | +| File name | xcassets/simple-swift4.stencil | +| Configuration example |
xcassets:
inputs: dir/to/search/for/imageset/assets
outputs:
templateName: simple-swift4
output: Assets.swift
| +| Language | Swift 4 | +| Author | Cihat Gündüz | + +## When to use it + +- When you need to generate *Swift 4* code. +- When you don't need trait collections. +- When you want to keep your calls short. + +It also takes into account any namespacing folder in your Assets Catalogs (i.e. if you create a folder in your Assets Catalog, select it, and check the "Provides Namespace" checkbox on the Attributes Inspector panel on the right) + +## Customization + +You can customize some elements of this template by overriding the following parameters when invoking `swiftgen`. See the [dedicated documentation](../../ConfigFile.md). + +| Parameter Name | Default Value | Description | +| -------------- | ------------- | ----------- | +| `enumName` | `Asset` | Allows you to change the name of the generated `enum` containing all assets. | +| `allValues` | N/A | Setting this parameter will enable the generation of the `allColors`, `allImages` and other such constants. | +| `publicAccess` | N/A | If set, the generated constants will be marked as `public`. Otherwise, they'll be declared `internal`. | +| `forceProvidesNamespaces` | N/A | If set, generates namespaces even for non namespacing asset folders (i.e. "Provides Namespace" is unchecked) | + +## Generated Code + +**Extract:** + +```swift +internal typealias Docs = Asset.Docs +internal typealias Exotic = Asset.Exotic +internal typealias Theme = Asset.Theme + +enum Asset { + enum Docs { + static let readme = NSDataAsset(name: "Readme", bundle: Bundle(for: BundleToken.self))!.data + } + enum Exotic { + static let banana = UIImage(named: "Exotic/Banana", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + static let mango = UIImage(named: "Exotic/Mango", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + } + static let json = NSDataAsset(name: "JSON", bundle: Bundle(for: BundleToken.self))!.data + static let `private` = UIImage(named: "private", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + enum Theme { + static let primary = UIColor(named: "Theme/Primary", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + static let background = UIColor(named: "Theme/Background", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + } +} +``` + +[Full generated code](../../../Tests/Fixtures/Generated/XCAssets/simple-swift4/all.swift) + +## Usage example + +```swift +// You can create new images by referring to the enum instance (via typealias if available): +let bananaImage: UIImage = Exotic.banana +let privateImage: UIImage = Asset.private + +// You can create data items by referring to the enum instance (via typealias if available): +let json: Data = Asset.json +let readme: Data = Docs.readme + +// You can create colors by referring to the enum instance and calling `.color` on it: +let primaryColor: UIColor = Theme.primary +let backgroundColor: UIColor = Theme.background +``` diff --git a/Documentation/templates/xcassets/swift4.md b/Documentation/templates/xcassets/swift4.md index 88f773297..afdc360cc 100644 --- a/Documentation/templates/xcassets/swift4.md +++ b/Documentation/templates/xcassets/swift4.md @@ -10,6 +10,7 @@ ## When to use it - When you need to generate *Swift 4* code. +- When you want a flexible solution that support trait collections & more. It also takes into account any namespacing folder in your Assets Catalogs (i.e. if you create a folder in your Assets Catalog, select it, and check the "Provides Namespace" checkbox on the Attributes Inspector panel on the right) diff --git a/SwiftGen.xcodeproj/xcshareddata/xcschemes/swiftgen.xcscheme b/SwiftGen.xcodeproj/xcshareddata/xcschemes/swiftgen.xcscheme index c32810e16..836e925c2 100644 --- a/SwiftGen.xcodeproj/xcshareddata/xcschemes/swiftgen.xcscheme +++ b/SwiftGen.xcodeproj/xcshareddata/xcschemes/swiftgen.xcscheme @@ -168,6 +168,10 @@ argument = "xcassets --templateName swift4 $(PROJECT_DIR)/Tests/Fixtures/Resources/XCAssets/Data.xcassets" isEnabled = "NO"> + + diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-allValues.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-allValues.swift new file mode 100644 index 000000000..d86ab8736 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-allValues.swift @@ -0,0 +1,84 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage +#endif + + +// MARK: - Asset Catalogs + +internal enum Asset { + internal enum Colors { + internal enum _24Vision { + internal static let background = ColorAsset(name: "24Vision/Background") + internal static let primary = ColorAsset(name: "24Vision/Primary") + } + internal static let orange = ImageAsset(name: "Orange") + internal enum Vengo { + internal static let primary = ColorAsset(name: "Vengo/Primary") + internal static let tint = ColorAsset(name: "Vengo/Tint") + } + internal static let allColors: [ColorAsset] = [ + _24Vision.background, + _24Vision.primary, + Vengo.primary, + Vengo.tint, + ] + internal static let allDataAssets: [DataAsset] = [ + ] + internal static let allImages: [ImageAsset] = [ + orange, + ] + } + internal enum Data { + internal static let data = DataAsset(name: "Data") + internal enum Json { + internal static let data = DataAsset(name: "Json/Data") + } + internal static let readme = DataAsset(name: "README") + internal static let allColors: [ColorAsset] = [ + ] + internal static let allDataAssets: [DataAsset] = [ + data, + Json.data, + readme, + ] + internal static let allImages: [ImageAsset] = [ + ] + } + internal enum Images { + internal enum Exotic { + internal static let banana = ImageAsset(name: "Exotic/Banana") + internal static let mango = ImageAsset(name: "Exotic/Mango") + } + internal enum Round { + internal static let apricot = ImageAsset(name: "Round/Apricot") + internal static let apple = ImageAsset(name: "Round/Apple") + internal enum Double { + internal static let cherry = ImageAsset(name: "Round/Double/Cherry") + } + internal static let tomato = ImageAsset(name: "Round/Tomato") + } + internal static let `private` = ImageAsset(name: "private") + internal static let allColors: [ColorAsset] = [ + ] + internal static let allDataAssets: [DataAsset] = [ + ] + internal static let allImages: [ImageAsset] = [ + Exotic.banana, + Exotic.mango, + Round.apricot, + Round.apple, + Round.Double.cherry, + Round.tomato, + `private`, + ] + } +} + +// MARK: - Implementation Details + +private final class BundleToken {} diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-customName.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-customName.swift new file mode 100644 index 000000000..a39de59f5 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-customName.swift @@ -0,0 +1,51 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage +#endif + + +// MARK: - Asset Catalogs + +internal enum XCTAssets { + internal enum Colors { + internal enum _24Vision { + internal static let background = XCTColorAsset(name: "24Vision/Background") + internal static let primary = XCTColorAsset(name: "24Vision/Primary") + } + internal static let orange = XCTImageAsset(name: "Orange") + internal enum Vengo { + internal static let primary = XCTColorAsset(name: "Vengo/Primary") + internal static let tint = XCTColorAsset(name: "Vengo/Tint") + } + } + internal enum Data { + internal static let data = XCTDataAsset(name: "Data") + internal enum Json { + internal static let data = XCTDataAsset(name: "Json/Data") + } + internal static let readme = XCTDataAsset(name: "README") + } + internal enum Images { + internal enum Exotic { + internal static let banana = XCTImageAsset(name: "Exotic/Banana") + internal static let mango = XCTImageAsset(name: "Exotic/Mango") + } + internal enum Round { + internal static let apricot = XCTImageAsset(name: "Round/Apricot") + internal static let apple = XCTImageAsset(name: "Round/Apple") + internal enum Double { + internal static let cherry = XCTImageAsset(name: "Round/Double/Cherry") + } + internal static let tomato = XCTImageAsset(name: "Round/Tomato") + } + internal static let `private` = XCTImageAsset(name: "private") + } +} + +// MARK: - Implementation Details + +private final class BundleToken {} diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-forceNamespaces.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-forceNamespaces.swift new file mode 100644 index 000000000..972a986d5 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-forceNamespaces.swift @@ -0,0 +1,53 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage +#endif + + +// MARK: - Asset Catalogs + +internal enum Asset { + internal enum Colors { + internal enum _24Vision { + internal static let background = ColorAsset(name: "24Vision/Background") + internal static let primary = ColorAsset(name: "24Vision/Primary") + } + internal static let orange = ImageAsset(name: "Orange") + internal enum Vengo { + internal static let primary = ColorAsset(name: "Vengo/Primary") + internal static let tint = ColorAsset(name: "Vengo/Tint") + } + } + internal enum Data { + internal static let data = DataAsset(name: "Data") + internal enum Json { + internal static let data = DataAsset(name: "Json/Data") + } + internal static let readme = DataAsset(name: "README") + } + internal enum Images { + internal enum Exotic { + internal static let banana = ImageAsset(name: "Exotic/Banana") + internal static let mango = ImageAsset(name: "Exotic/Mango") + } + internal enum Round { + internal static let apricot = ImageAsset(name: "Round/Apricot") + internal enum Red { + internal static let apple = ImageAsset(name: "Round/Apple") + internal enum Double { + internal static let cherry = ImageAsset(name: "Round/Double/Cherry") + } + internal static let tomato = ImageAsset(name: "Round/Tomato") + } + } + internal static let `private` = ImageAsset(name: "private") + } +} + +// MARK: - Implementation Details + +private final class BundleToken {} diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-publicAccess.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-publicAccess.swift new file mode 100644 index 000000000..bcc910f3a --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all-publicAccess.swift @@ -0,0 +1,51 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage +#endif + + +// MARK: - Asset Catalogs + +public enum Asset { + public enum Colors { + public enum _24Vision { + public static let background = ColorAsset(name: "24Vision/Background") + public static let primary = ColorAsset(name: "24Vision/Primary") + } + public static let orange = ImageAsset(name: "Orange") + public enum Vengo { + public static let primary = ColorAsset(name: "Vengo/Primary") + public static let tint = ColorAsset(name: "Vengo/Tint") + } + } + public enum Data { + public static let data = DataAsset(name: "Data") + public enum Json { + public static let data = DataAsset(name: "Json/Data") + } + public static let readme = DataAsset(name: "README") + } + public enum Images { + public enum Exotic { + public static let banana = ImageAsset(name: "Exotic/Banana") + public static let mango = ImageAsset(name: "Exotic/Mango") + } + public enum Round { + public static let apricot = ImageAsset(name: "Round/Apricot") + public static let apple = ImageAsset(name: "Round/Apple") + public enum Double { + public static let cherry = ImageAsset(name: "Round/Double/Cherry") + } + public static let tomato = ImageAsset(name: "Round/Tomato") + } + public static let `private` = ImageAsset(name: "private") + } +} + +// MARK: - Implementation Details + +private final class BundleToken {} diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/all.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all.swift new file mode 100644 index 000000000..5edad7559 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/all.swift @@ -0,0 +1,51 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +#if os(OSX) + import AppKit.NSImage +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage +#endif + + +// MARK: - Asset Catalogs + +internal enum Asset { + internal enum Colors { + internal enum _24Vision { + internal static let background = ColorAsset(name: "24Vision/Background") + internal static let primary = ColorAsset(name: "24Vision/Primary") + } + internal static let orange = ImageAsset(name: "Orange") + internal enum Vengo { + internal static let primary = ColorAsset(name: "Vengo/Primary") + internal static let tint = ColorAsset(name: "Vengo/Tint") + } + } + internal enum Data { + internal static let data = DataAsset(name: "Data") + internal enum Json { + internal static let data = DataAsset(name: "Json/Data") + } + internal static let readme = DataAsset(name: "README") + } + internal enum Images { + internal enum Exotic { + internal static let banana = ImageAsset(name: "Exotic/Banana") + internal static let mango = ImageAsset(name: "Exotic/Mango") + } + internal enum Round { + internal static let apricot = ImageAsset(name: "Round/Apricot") + internal static let apple = ImageAsset(name: "Round/Apple") + internal enum Double { + internal static let cherry = ImageAsset(name: "Round/Double/Cherry") + } + internal static let tomato = ImageAsset(name: "Round/Tomato") + } + internal static let `private` = ImageAsset(name: "private") + } +} + +// MARK: - Implementation Details + +private final class BundleToken {} diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/compilation-configuration.yml b/Tests/Fixtures/Generated/XCAssets/simple-swift4/compilation-configuration.yml new file mode 100644 index 000000000..cb9fcae69 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/compilation-configuration.yml @@ -0,0 +1,5 @@ +--- !ruby/object:CompilationConfiguration +common: + swift_versions: + - 4 + - 4.2 diff --git a/Tests/Fixtures/Generated/XCAssets/simple-swift4/empty.swift b/Tests/Fixtures/Generated/XCAssets/simple-swift4/empty.swift new file mode 100644 index 000000000..bc0f47155 --- /dev/null +++ b/Tests/Fixtures/Generated/XCAssets/simple-swift4/empty.swift @@ -0,0 +1,4 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +// No assets found diff --git a/Tests/TemplatesTests/XCAssetsTests.swift b/Tests/TemplatesTests/XCAssetsTests.swift index 02aa5e974..7c7e5b82f 100644 --- a/Tests/TemplatesTests/XCAssetsTests.swift +++ b/Tests/TemplatesTests/XCAssetsTests.swift @@ -59,4 +59,13 @@ class XCAssetsTests: XCTestCase { contextVariations: variations ) } + + func testSimpleSwift4() { + test( + template: "simple-swift4", + contextNames: Contexts.all, + directory: .xcassets, + contextVariations: variations + ) + } } diff --git a/templates/xcassets/simple-swift4.stencil b/templates/xcassets/simple-swift4.stencil new file mode 100644 index 000000000..a84525554 --- /dev/null +++ b/templates/xcassets/simple-swift4.stencil @@ -0,0 +1,90 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +{% if catalogs %} +{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %} +{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %} +{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %} +#if os(OSX) + import AppKit.NSImage + {% set colorType %}NSColor{% endset %} + {% set imageType %}NSImage{% endset %} +#elseif os(iOS) || os(tvOS) || os(watchOS) + import UIKit.UIImage + {% set colorType %}UIColor{% endset %} + {% set imageType %}UIImage{% endset %} +#endif + +// MARK: - Asset Catalogs + +{% macro enumBlock assets %} + {% call casesBlock assets %} + {% if param.allValues %} + + {{accessModifier}} static let allColors: [{{colorType}}] = [ + {% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %} + ] + {{accessModifier}} static let allDataAssets: [Data] = [ + {% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %} + ] + {{accessModifier}} static let allImages: [{{imageType}}] = [ + {% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %} + ] + {% endif %} +{% endmacro %} +{% macro casesBlock assets %} + {% for asset in assets %} + {% if asset.type == "color" %} + {{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(named: "{{asset.value}}", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + {% elif asset.type == "data" %} + {{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = NSDataAsset(name: "{{asset.value}}", bundle: Bundle(for: BundleToken.self))!.data + {% elif asset.type == "image" %} + {{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(named: "{{asset.value}}", in: Bundle(for: BundleToken.self), compatibleWith: nil)! + {% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %} + {{accessModifier}} enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} { + + {% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %} + } + {% elif asset.items %} + {% call casesBlock asset.items %} + {% endif %} + {% endfor %} +{% endmacro %} +{% macro allValuesBlock assets filter prefix %} + {% for asset in assets %} + {% if asset.type == filter %} + {{prefix}}{{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}, + {% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %} + {% set prefix2 %}{{prefix}}{{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.{% endset %} + {% call allValuesBlock asset.items filter prefix2 %} + {% elif asset.items %} + {% call allValuesBlock asset.items filter prefix %} + {% endif %} + {% endfor %} +{% endmacro %} +{% if catalogs.count > 1 %} +{% for catalog in catalogs %} +{{accessModifier}} typealias {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} = {{enumName}}.{{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} +{% endfor %} +{% else %} +{% call enumBlock catalogs.first.assets %} +{% endif %} + +{{accessModifier}} enum {{enumName}} { + {% if catalogs.count > 1 %} + {% for catalog in catalogs %} + {{accessModifier}} enum {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} { + {% filter indent:2 %}{% call enumBlock catalog.assets %}{% endfilter %} + } + {% endfor %} + {% else %} + {% call enumBlock catalogs.first.assets %} + {% endif %} +} + +// MARK: - Implementation Details + +private final class BundleToken {} +{% else %} +// No assets found +{% endif %}