Compare commits
53 commits
Author | SHA1 | Date | |
---|---|---|---|
fmodf | 48d7030090 | ||
fmodf | 2d8019217a | ||
fmodf | 43dde437c5 | ||
fmodf | 20db5d5f2d | ||
fmodf | 7424e9171a | ||
fmodf | 6906c094ea | ||
fmodf | 3ab551e8de | ||
fmodf | 1c745f2b25 | ||
fmodf | 4717aa8649 | ||
fmodf | f387236d9d | ||
fmodf | 80c56f1d48 | ||
fmodf | 43f01272ab | ||
fmodf | 1a51090b03 | ||
fmodf | dba6463116 | ||
fmodf | 1f414b9344 | ||
fmodf | fc4610192b | ||
fmodf | 50feee4f74 | ||
fmodf | 9df49aa422 | ||
fmodf | 2736e72e9d | ||
fmodf | 4d7e8d2fbd | ||
fmodf | 4c6aaea4d8 | ||
fmodf | cad4d3dcb0 | ||
fmodf | 3e668aa808 | ||
fmodf | 54f2b3b825 | ||
fmodf | f33c3de839 | ||
fmodf | c95460b80e | ||
fmodf | cc20619e2c | ||
fmodf | f1fd81841e | ||
fmodf | 7603ace54e | ||
fmodf | b75eed2677 | ||
fmodf | d62937af4b | ||
fmodf | ab08d43225 | ||
fmodf | 507bc16846 | ||
fmodf | ac6eb97b16 | ||
fmodf | f31f0c54c5 | ||
fmodf | 8cbd60d30d | ||
fmodf | 93ee79ee20 | ||
fmodf | a7fddc9022 | ||
fmodf | 4316eb2ca1 | ||
fmodf | 4b4de74eda | ||
fmodf | 4d02aaea5b | ||
fmodf | 97ac8373c9 | ||
fmodf | 68a136e4b7 | ||
fmodf | aaa5428bfc | ||
fmodf | 39b8a4c6bc | ||
fmodf | 050a12b1cc | ||
fmodf | f9d776da64 | ||
fmodf | 129b63fd16 | ||
fmodf | 0535e59bb3 | ||
fmodf | 05d79d058f | ||
fmodf | eefce61e3a | ||
fmodf | 44f3c598cd | ||
fmodf | ac15a7e8c5 |
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -110,4 +110,9 @@ xcuserdata
|
|||
#
|
||||
# We're using source-control, so this is a "feature" that we do not want!
|
||||
|
||||
*.moved-aside
|
||||
*.moved-aside
|
||||
/.idea
|
||||
/Snikket/.idea
|
||||
/Snikket.xcodeproj
|
||||
/Info.plist
|
||||
/old/.idea
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string></string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>SwiftGen_SwiftGenCLI</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>SwiftGen.SwiftGenCLI.resources</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>SwiftGen_SwiftGenCLI</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>13A233</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>macosx</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>11.3</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>20E214</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx11.3</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1300</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>13A233</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.11</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,43 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if palettes %}
|
||||
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit
|
||||
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||
#endif
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Colors
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} extension {{enumName}} {
|
||||
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
|
||||
{% macro enumBlock colors accessPrefix %}
|
||||
{% for color in colors %}
|
||||
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
|
||||
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||
{% set accessPrefix %}{{accessModifier}} {% endset %}
|
||||
{% for palette in palettes %}
|
||||
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call enumBlock palettes.first.colors "" %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
{% else %}
|
||||
// No color found
|
||||
{% endif %}
|
|
@ -0,0 +1,43 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if palettes %}
|
||||
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit
|
||||
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
|
||||
#endif
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Colors
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} extension {{enumName}} {
|
||||
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
|
||||
{% macro enumBlock colors accessPrefix %}
|
||||
{% for color in colors %}
|
||||
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
|
||||
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||
{% set accessPrefix %}{{accessModifier}} {% endset %}
|
||||
{% for palette in palettes %}
|
||||
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call enumBlock palettes.first.colors "" %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
{% else %}
|
||||
// No color found
|
||||
{% endif %}
|
|
@ -0,0 +1,84 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if palettes %}
|
||||
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit.NSColor
|
||||
{{accessModifier}} typealias {{colorAlias}} = NSColor
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit.UIColor
|
||||
{{accessModifier}} typealias {{colorAlias}} = UIColor
|
||||
#endif
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Colors
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||
{{accessModifier}} struct {{enumName}} {
|
||||
{{accessModifier}} let rgbaValue: UInt32
|
||||
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
|
||||
|
||||
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
|
||||
{% macro enumBlock colors %}
|
||||
{% for color in colors %}
|
||||
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
|
||||
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
|
||||
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||
{% for palette in palettes %}
|
||||
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call enumBlock palettes.first.colors %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
internal extension {{colorAlias}} {
|
||||
convenience init(rgbaValue: UInt32) {
|
||||
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
|
||||
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
|
||||
}
|
||||
}
|
||||
|
||||
private struct RGBAComponents {
|
||||
let rgbaValue: UInt32
|
||||
|
||||
private var shifts: [UInt32] {
|
||||
[
|
||||
rgbaValue >> 24, // red
|
||||
rgbaValue >> 16, // green
|
||||
rgbaValue >> 8, // blue
|
||||
rgbaValue // alpha
|
||||
]
|
||||
}
|
||||
|
||||
private var components: [CGFloat] {
|
||||
shifts.map {
|
||||
CGFloat($0 & 0xff)
|
||||
}
|
||||
}
|
||||
|
||||
var normalized: [CGFloat] {
|
||||
components.map { $0 / 255.0 }
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{colorAlias}} {
|
||||
convenience init(named color: {{enumName}}) {
|
||||
self.init(rgbaValue: color.rgbaValue)
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
// No color found
|
||||
{% endif %}
|
|
@ -0,0 +1,84 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if palettes %}
|
||||
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit.NSColor
|
||||
{{accessModifier}} typealias {{colorAlias}} = NSColor
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit.UIColor
|
||||
{{accessModifier}} typealias {{colorAlias}} = UIColor
|
||||
#endif
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Colors
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
|
||||
{{accessModifier}} struct {{enumName}} {
|
||||
{{accessModifier}} let rgbaValue: UInt32
|
||||
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
|
||||
|
||||
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
|
||||
{% macro enumBlock colors %}
|
||||
{% for color in colors %}
|
||||
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
|
||||
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
|
||||
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% if palettes.count > 1 or param.forceFileNameEnum %}
|
||||
{% for palette in palettes %}
|
||||
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call enumBlock palettes.first.colors %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
internal extension {{colorAlias}} {
|
||||
convenience init(rgbaValue: UInt32) {
|
||||
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
|
||||
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
|
||||
}
|
||||
}
|
||||
|
||||
private struct RGBAComponents {
|
||||
let rgbaValue: UInt32
|
||||
|
||||
private var shifts: [UInt32] {
|
||||
[
|
||||
rgbaValue >> 24, // red
|
||||
rgbaValue >> 16, // green
|
||||
rgbaValue >> 8, // blue
|
||||
rgbaValue // alpha
|
||||
]
|
||||
}
|
||||
|
||||
private var components: [CGFloat] {
|
||||
shifts.map {
|
||||
CGFloat($0 & 0xff)
|
||||
}
|
||||
}
|
||||
|
||||
var normalized: [CGFloat] {
|
||||
components.map { $0 / 255.0 }
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{colorAlias}} {
|
||||
convenience init(named color: {{enumName}}) {
|
||||
self.init(rgbaValue: color.rgbaValue)
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
// No color found
|
||||
{% endif %}
|
|
@ -0,0 +1,211 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
// swiftlint:disable superfluous_disable_command implicit_return
|
||||
// swiftlint:disable sorted_imports
|
||||
import CoreData
|
||||
import Foundation
|
||||
{% for import in param.extraImports %}
|
||||
import {{ import }}
|
||||
{% empty %}
|
||||
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
|
||||
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
|
||||
{% for model in models %}
|
||||
{% for name, entity in model.entities %}
|
||||
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
|
||||
// MARK: - {{ entity.name }}
|
||||
|
||||
{% if not entity.shouldGenerateCode %}
|
||||
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
|
||||
|
||||
{% elif entityClassName|contains:"." %}
|
||||
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
|
||||
|
||||
{% else %}
|
||||
{% if param.generateObjcName %}
|
||||
@objc({{ entityClassName }})
|
||||
{% endif %}
|
||||
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
|
||||
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
|
||||
{{ override }}{{ accessModifier }} class var entityName: String {
|
||||
return "{{ entity.name }}"
|
||||
}
|
||||
|
||||
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
|
||||
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
|
||||
}
|
||||
|
||||
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
|
||||
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||
}
|
||||
|
||||
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||
}
|
||||
|
||||
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
|
||||
{% for attribute in entity.attributes %}
|
||||
{% if attribute.userInfo.RawType %}
|
||||
{% set rawType attribute.userInfo.RawType %}
|
||||
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
|
||||
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
|
||||
get {
|
||||
let key = "{{ attribute.name }}"
|
||||
willAccessValue(forKey: key)
|
||||
defer { didAccessValue(forKey: key) }
|
||||
|
||||
{% if unwrapOptional %}
|
||||
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
|
||||
let result = {{ rawType }}(rawValue: value) else {
|
||||
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
|
||||
}
|
||||
return result
|
||||
{% else %}
|
||||
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
|
||||
return nil
|
||||
}
|
||||
return {{ rawType }}(rawValue: value)
|
||||
{% endif %}
|
||||
}
|
||||
set {
|
||||
let key = "{{ attribute.name }}"
|
||||
willChangeValue(forKey: key)
|
||||
defer { didChangeValue(forKey: key) }
|
||||
|
||||
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
|
||||
}
|
||||
}
|
||||
{% elif attribute.usesScalarValueType and attribute.isOptional %}
|
||||
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
|
||||
get {
|
||||
let key = "{{ attribute.name }}"
|
||||
willAccessValue(forKey: key)
|
||||
defer { didAccessValue(forKey: key) }
|
||||
|
||||
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
|
||||
}
|
||||
set {
|
||||
let key = "{{ attribute.name }}"
|
||||
willChangeValue(forKey: key)
|
||||
defer { didChangeValue(forKey: key) }
|
||||
|
||||
setPrimitiveValue(newValue, forKey: key)
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for relationship in entity.relationships %}
|
||||
{% if relationship.isToMany %}
|
||||
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
|
||||
{% else %}
|
||||
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for fetchedProperty in entity.fetchedProperties %}
|
||||
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
|
||||
{% endfor %}
|
||||
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
|
||||
}
|
||||
|
||||
{% for relationship in entity.relationships where relationship.isToMany %}
|
||||
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
|
||||
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
|
||||
// MARK: Relationship {{ relationshipName }}
|
||||
|
||||
extension {{ entityClassName }} {
|
||||
{% if relationship.isOrdered %}
|
||||
@objc(insertObject:in{{ relationshipName }}AtIndex:)
|
||||
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
|
||||
|
||||
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
|
||||
|
||||
@objc(insert{{ relationshipName }}:atIndexes:)
|
||||
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
|
||||
|
||||
@objc(remove{{ relationshipName }}AtIndexes:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
|
||||
|
||||
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
|
||||
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
|
||||
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
|
||||
|
||||
{% endif %}
|
||||
@objc(add{{ relationshipName }}Object:)
|
||||
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(remove{{ relationshipName }}Object:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(add{{ relationshipName }}:)
|
||||
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||
|
||||
@objc(remove{{ relationshipName }}:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
{% if model.fetchRequests[entity.name].count > 0 %}
|
||||
// MARK: Fetch Requests
|
||||
|
||||
extension {{ entityClassName }} {
|
||||
{% for fetchRequest in model.fetchRequests[entity.name] %}
|
||||
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
|
||||
{% if fetchRequest.resultType == "Object" %}
|
||||
{{ entityClassName }}
|
||||
{% elif fetchRequest.resultType == "Object ID" %}
|
||||
NSManagedObjectID
|
||||
{% elif fetchRequest.resultType == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% endif %}
|
||||
{% endfilter %}{% endset %}
|
||||
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
|
||||
managedObjectContext: NSManagedObjectContext
|
||||
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||
, {{ variableName | lowerFirstWord }}: {{ variableType }}
|
||||
{% endfor %}
|
||||
{% endfilter %}) throws -> [{{ resultTypeName }}] {
|
||||
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
|
||||
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
|
||||
}
|
||||
let model = persistentStoreCoordinator.managedObjectModel
|
||||
let substitutionVariables: [String: Any] = [
|
||||
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
|
||||
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
|
||||
}
|
||||
|
||||
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
|
||||
fatalError("Unable to cast fetch result to correct result type.")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
|
@ -0,0 +1,211 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
// swiftlint:disable superfluous_disable_command implicit_return
|
||||
// swiftlint:disable sorted_imports
|
||||
import CoreData
|
||||
import Foundation
|
||||
{% for import in param.extraImports %}
|
||||
import {{ import }}
|
||||
{% empty %}
|
||||
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
|
||||
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
|
||||
{% for model in models %}
|
||||
{% for name, entity in model.entities %}
|
||||
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
|
||||
// MARK: - {{ entity.name }}
|
||||
|
||||
{% if not entity.shouldGenerateCode %}
|
||||
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
|
||||
|
||||
{% elif entityClassName|contains:"." %}
|
||||
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
|
||||
|
||||
{% else %}
|
||||
{% if param.generateObjcName %}
|
||||
@objc({{ entityClassName }})
|
||||
{% endif %}
|
||||
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
|
||||
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
|
||||
{{ override }}{{ accessModifier }} class var entityName: String {
|
||||
return "{{ entity.name }}"
|
||||
}
|
||||
|
||||
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
|
||||
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
|
||||
}
|
||||
|
||||
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
|
||||
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||
}
|
||||
|
||||
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
|
||||
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
|
||||
}
|
||||
|
||||
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
|
||||
{% for attribute in entity.attributes %}
|
||||
{% if attribute.userInfo.RawType %}
|
||||
{% set rawType attribute.userInfo.RawType %}
|
||||
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
|
||||
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
|
||||
get {
|
||||
let key = "{{ attribute.name }}"
|
||||
willAccessValue(forKey: key)
|
||||
defer { didAccessValue(forKey: key) }
|
||||
|
||||
{% if unwrapOptional %}
|
||||
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
|
||||
let result = {{ rawType }}(rawValue: value) else {
|
||||
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
|
||||
}
|
||||
return result
|
||||
{% else %}
|
||||
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
|
||||
return nil
|
||||
}
|
||||
return {{ rawType }}(rawValue: value)
|
||||
{% endif %}
|
||||
}
|
||||
set {
|
||||
let key = "{{ attribute.name }}"
|
||||
willChangeValue(forKey: key)
|
||||
defer { didChangeValue(forKey: key) }
|
||||
|
||||
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
|
||||
}
|
||||
}
|
||||
{% elif attribute.usesScalarValueType and attribute.isOptional %}
|
||||
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
|
||||
get {
|
||||
let key = "{{ attribute.name }}"
|
||||
willAccessValue(forKey: key)
|
||||
defer { didAccessValue(forKey: key) }
|
||||
|
||||
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
|
||||
}
|
||||
set {
|
||||
let key = "{{ attribute.name }}"
|
||||
willChangeValue(forKey: key)
|
||||
defer { didChangeValue(forKey: key) }
|
||||
|
||||
setPrimitiveValue(newValue, forKey: key)
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for relationship in entity.relationships %}
|
||||
{% if relationship.isToMany %}
|
||||
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
|
||||
{% else %}
|
||||
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for fetchedProperty in entity.fetchedProperties %}
|
||||
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
|
||||
{% endfor %}
|
||||
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
|
||||
}
|
||||
|
||||
{% for relationship in entity.relationships where relationship.isToMany %}
|
||||
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
|
||||
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
|
||||
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
|
||||
// MARK: Relationship {{ relationshipName }}
|
||||
|
||||
extension {{ entityClassName }} {
|
||||
{% if relationship.isOrdered %}
|
||||
@objc(insertObject:in{{ relationshipName }}AtIndex:)
|
||||
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
|
||||
|
||||
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
|
||||
|
||||
@objc(insert{{ relationshipName }}:atIndexes:)
|
||||
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
|
||||
|
||||
@objc(remove{{ relationshipName }}AtIndexes:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
|
||||
|
||||
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
|
||||
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
|
||||
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
|
||||
|
||||
{% endif %}
|
||||
@objc(add{{ relationshipName }}Object:)
|
||||
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(remove{{ relationshipName }}Object:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
|
||||
|
||||
@objc(add{{ relationshipName }}:)
|
||||
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||
|
||||
@objc(remove{{ relationshipName }}:)
|
||||
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
{% if model.fetchRequests[entity.name].count > 0 %}
|
||||
// MARK: Fetch Requests
|
||||
|
||||
extension {{ entityClassName }} {
|
||||
{% for fetchRequest in model.fetchRequests[entity.name] %}
|
||||
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
|
||||
{% if fetchRequest.resultType == "Object" %}
|
||||
{{ entityClassName }}
|
||||
{% elif fetchRequest.resultType == "Object ID" %}
|
||||
NSManagedObjectID
|
||||
{% elif fetchRequest.resultType == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% endif %}
|
||||
{% endfilter %}{% endset %}
|
||||
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
|
||||
managedObjectContext: NSManagedObjectContext
|
||||
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||
, {{ variableName | lowerFirstWord }}: {{ variableType }}
|
||||
{% endfor %}
|
||||
{% endfilter %}) throws -> [{{ resultTypeName }}] {
|
||||
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
|
||||
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
|
||||
}
|
||||
let model = persistentStoreCoordinator.managedObjectModel
|
||||
let substitutionVariables: [String: Any] = [
|
||||
{% for variableName, variableType in fetchRequest.substitutionVariables %}
|
||||
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
|
||||
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
|
||||
}
|
||||
|
||||
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
|
||||
fatalError("Unable to cast fetch result to correct result type.")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
|
@ -0,0 +1,103 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if groups.count > 0 %}
|
||||
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||
|
||||
// MARK: - Files
|
||||
|
||||
{% macro groupBlock group %}
|
||||
{% for file in group.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in group.directories %}
|
||||
{% call dirBlock dir %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% macro fileBlock file %}
|
||||
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||
{% endmacro %}
|
||||
{% macro dirBlock directory %}
|
||||
{% for file in directory.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in directory.directories %}
|
||||
{% call dirBlock dir %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface identifier_name
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||
{% for group in groups %}
|
||||
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call groupBlock groups.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{resourceType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let ext: String?
|
||||
{{accessModifier}} let relativePath: String
|
||||
{{accessModifier}} let mimeType: String
|
||||
|
||||
{{accessModifier}} var url: URL {
|
||||
return url(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
let url = bundle.url(
|
||||
forResource: name,
|
||||
withExtension: ext,
|
||||
subdirectory: relativePath,
|
||||
localization: locale?.identifier
|
||||
)
|
||||
guard let result = url else {
|
||||
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||
fatalError("Could not locate file named \(file)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
{{accessModifier}} var path: String {
|
||||
return path(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||
return url(locale: locale).path
|
||||
}
|
||||
}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type explicit_type_interface
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type explicit_type_interface
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,103 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if groups.count > 0 %}
|
||||
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||
|
||||
// MARK: - Files
|
||||
|
||||
{% macro groupBlock group %}
|
||||
{% for file in group.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in group.directories %}
|
||||
{% call dirBlock dir %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% macro fileBlock file %}
|
||||
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||
{% endmacro %}
|
||||
{% macro dirBlock directory %}
|
||||
{% for file in directory.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in directory.directories %}
|
||||
{% call dirBlock dir %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface identifier_name
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||
{% for group in groups %}
|
||||
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call groupBlock groups.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{resourceType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let ext: String?
|
||||
{{accessModifier}} let relativePath: String
|
||||
{{accessModifier}} let mimeType: String
|
||||
|
||||
{{accessModifier}} var url: URL {
|
||||
return url(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
let url = bundle.url(
|
||||
forResource: name,
|
||||
withExtension: ext,
|
||||
subdirectory: relativePath,
|
||||
localization: locale?.identifier
|
||||
)
|
||||
guard let result = url else {
|
||||
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||
fatalError("Could not locate file named \(file)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
{{accessModifier}} var path: String {
|
||||
return path(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||
return url(locale: locale).path
|
||||
}
|
||||
}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type explicit_type_interface
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type explicit_type_interface
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,107 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if groups.count > 0 %}
|
||||
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||
|
||||
// MARK: - Files
|
||||
|
||||
{% macro groupBlock group %}
|
||||
{% for file in group.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in group.directories %}
|
||||
{% call dirBlock dir "" %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% macro fileBlock file %}
|
||||
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||
{% endmacro %}
|
||||
{% macro dirBlock directory parent %}
|
||||
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
|
||||
/// {{ fullDir }}
|
||||
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% for file in directory.files %}
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
{% endfor %}
|
||||
{% for dir in directory.directories %}
|
||||
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface identifier_name
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||
{% for group in groups %}
|
||||
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call groupBlock groups.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{resourceType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let ext: String?
|
||||
{{accessModifier}} let relativePath: String
|
||||
{{accessModifier}} let mimeType: String
|
||||
|
||||
{{accessModifier}} var url: URL {
|
||||
return url(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
let url = bundle.url(
|
||||
forResource: name,
|
||||
withExtension: ext,
|
||||
subdirectory: relativePath,
|
||||
localization: locale?.identifier
|
||||
)
|
||||
guard let result = url else {
|
||||
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||
fatalError("Could not locate file named \(file)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
{{accessModifier}} var path: String {
|
||||
return path(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||
return url(locale: locale).path
|
||||
}
|
||||
}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type explicit_type_interface
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type explicit_type_interface
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,107 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if groups.count > 0 %}
|
||||
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
|
||||
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
|
||||
|
||||
// MARK: - Files
|
||||
|
||||
{% macro groupBlock group %}
|
||||
{% for file in group.files %}
|
||||
{% call fileBlock file %}
|
||||
{% endfor %}
|
||||
{% for dir in group.directories %}
|
||||
{% call dirBlock dir "" %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% macro fileBlock file %}
|
||||
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
|
||||
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
|
||||
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
|
||||
{% endmacro %}
|
||||
{% macro dirBlock directory parent %}
|
||||
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
|
||||
/// {{ fullDir }}
|
||||
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% for file in directory.files %}
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
{% endfor %}
|
||||
{% for dir in directory.directories %}
|
||||
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface identifier_name
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if groups.count > 1 or param.forceFileNameEnum %}
|
||||
{% for group in groups %}
|
||||
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call groupBlock groups.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{resourceType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let ext: String?
|
||||
{{accessModifier}} let relativePath: String
|
||||
{{accessModifier}} let mimeType: String
|
||||
|
||||
{{accessModifier}} var url: URL {
|
||||
return url(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func url(locale: Locale?) -> URL {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
let url = bundle.url(
|
||||
forResource: name,
|
||||
withExtension: ext,
|
||||
subdirectory: relativePath,
|
||||
localization: locale?.identifier
|
||||
)
|
||||
guard let result = url else {
|
||||
let file = name + (ext.flatMap { ".\($0)" } ?? "")
|
||||
fatalError("Could not locate file named \(file)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
{{accessModifier}} var path: String {
|
||||
return path(locale: nil)
|
||||
}
|
||||
|
||||
{{accessModifier}} func path(locale: Locale?) -> String {
|
||||
return url(locale: locale).path
|
||||
}
|
||||
}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type explicit_type_interface
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type explicit_type_interface
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,110 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if families %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit.NSFont
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit.UIFont
|
||||
#endif
|
||||
|
||||
// Deprecated typealiases
|
||||
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
// swiftlint:disable implicit_return
|
||||
|
||||
// MARK: - Fonts
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
|
||||
{% for family in families %}
|
||||
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% for font in family.fonts %}
|
||||
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
|
||||
{% endfor %}
|
||||
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
|
||||
}
|
||||
{% endfor %}
|
||||
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
|
||||
{{accessModifier}} static func registerAllCustomFonts() {
|
||||
allCustomFonts.forEach { $0.register() }
|
||||
}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{fontType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let family: String
|
||||
{{accessModifier}} let path: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Font = NSFont
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Font = UIFont
|
||||
#endif
|
||||
|
||||
{{accessModifier}} func font(size: CGFloat) -> Font! {
|
||||
return Font(font: self, size: size)
|
||||
}
|
||||
|
||||
{{accessModifier}} func register() {
|
||||
// swiftlint:disable:next conditional_returns_on_newline
|
||||
guard let url = url else { return }
|
||||
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
|
||||
}
|
||||
|
||||
fileprivate var url: URL? {
|
||||
{% if param.lookupFunction %}
|
||||
return {{param.lookupFunction}}(name, family, path)
|
||||
{% else %}
|
||||
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{fontType}}.Font {
|
||||
convenience init?(font: {{fontType}}, size: CGFloat) {
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
|
||||
font.register()
|
||||
}
|
||||
#elseif os(macOS)
|
||||
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
|
||||
font.register()
|
||||
}
|
||||
#endif
|
||||
|
||||
self.init(name: font.name, size: size)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No fonts found
|
||||
{% endif %}
|
|
@ -0,0 +1,113 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if families %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit.NSFont
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
import UIKit.UIFont
|
||||
#endif
|
||||
|
||||
// Deprecated typealiases
|
||||
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Fonts
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
|
||||
{% for family in families %}
|
||||
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% for font in family.fonts %}
|
||||
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
|
||||
{% endfor %}
|
||||
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
|
||||
}
|
||||
{% endfor %}
|
||||
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
|
||||
{{accessModifier}} static func registerAllCustomFonts() {
|
||||
allCustomFonts.forEach { $0.register() }
|
||||
}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} struct {{fontType}} {
|
||||
{{accessModifier}} let name: String
|
||||
{{accessModifier}} let family: String
|
||||
{{accessModifier}} let path: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Font = NSFont
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Font = UIFont
|
||||
#endif
|
||||
|
||||
{{accessModifier}} func font(size: CGFloat) -> Font {
|
||||
guard let font = Font(font: self, size: size) else {
|
||||
fatalError("Unable to initialize font '\(name)' (\(family))")
|
||||
}
|
||||
return font
|
||||
}
|
||||
|
||||
{{accessModifier}} func register() {
|
||||
// swiftlint:disable:next conditional_returns_on_newline
|
||||
guard let url = url else { return }
|
||||
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
|
||||
}
|
||||
|
||||
fileprivate var url: URL? {
|
||||
// swiftlint:disable:next implicit_return
|
||||
{% if param.lookupFunction %}
|
||||
return {{param.lookupFunction}}(name, family, path)
|
||||
{% else %}
|
||||
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{fontType}}.Font {
|
||||
convenience init?(font: {{fontType}}, size: CGFloat) {
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
|
||||
font.register()
|
||||
}
|
||||
#elseif os(macOS)
|
||||
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
|
||||
font.register()
|
||||
}
|
||||
#endif
|
||||
|
||||
self.init(name: font.name, size: size)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No fonts found
|
||||
{% endif %}
|
|
@ -0,0 +1,157 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if platform and storyboards %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
|
||||
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
|
||||
// swiftlint:disable sorted_imports
|
||||
import Foundation
|
||||
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||
import {{module}}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length implicit_return
|
||||
|
||||
// MARK: - Storyboard Scenes
|
||||
|
||||
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
{% macro moduleName item %}{% filter removeNewlines %}
|
||||
{% if item.moduleIsPlaceholder %}
|
||||
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
|
||||
{% else %}
|
||||
{{ item.module }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro className item %}{% filter removeNewlines %}
|
||||
{% set module %}{% call moduleName item %}{% endset %}
|
||||
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
|
||||
{{module}}.
|
||||
{% endif %}
|
||||
{{item.type}}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
|
||||
{% for storyboard in storyboards %}
|
||||
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
|
||||
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
|
||||
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
|
||||
{% if storyboard.initialScene %}
|
||||
|
||||
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
|
||||
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
|
||||
{% endif %}
|
||||
{% for scene in storyboard.scenes %}
|
||||
|
||||
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set sceneClass %}{% call className scene %}{% endset %}
|
||||
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} protocol StoryboardType {
|
||||
static var storyboardName: String { get }
|
||||
}
|
||||
|
||||
{{accessModifier}} extension StoryboardType {
|
||||
static var storyboard: {{prefix}}Storyboard {
|
||||
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
|
||||
{% if param.lookupFunction %}
|
||||
return {{param.lookupFunction}}(name)
|
||||
{% else %}
|
||||
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||
{{accessModifier}} let identifier: String
|
||||
|
||||
{{accessModifier}} func instantiate() -> T {
|
||||
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
|
||||
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
|
||||
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
{% if isAppKit %}
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
{% else %}
|
||||
@available(iOS 13.0, tvOS 13.0, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||
|
||||
{{accessModifier}} func instantiate() -> T {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
|
||||
fatalError("{{controller}} is not of the expected class \(T.self).")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
{% if isAppKit %}
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
{% else %}
|
||||
@available(iOS 13.0, tvOS 13.0, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% elif storyboards %}
|
||||
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||
{% else %}
|
||||
// No storyboard found
|
||||
{% endif %}
|
|
@ -0,0 +1,159 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if platform and storyboards %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
|
||||
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
|
||||
// swiftlint:disable sorted_imports
|
||||
import Foundation
|
||||
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||
import {{module}}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length implicit_return
|
||||
|
||||
// MARK: - Storyboard Scenes
|
||||
|
||||
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
{% macro moduleName item %}{% filter removeNewlines %}
|
||||
{% if item.moduleIsPlaceholder %}
|
||||
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
|
||||
{% else %}
|
||||
{{ item.module }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro className item %}{% filter removeNewlines %}
|
||||
{% set module %}{% call moduleName item %}{% endset %}
|
||||
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
|
||||
{{module}}.
|
||||
{% endif %}
|
||||
{{item.type}}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
|
||||
{% for storyboard in storyboards %}
|
||||
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
|
||||
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
|
||||
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
|
||||
{% if storyboard.initialScene %}
|
||||
|
||||
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
|
||||
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
|
||||
{% endif %}
|
||||
{% for scene in storyboard.scenes %}
|
||||
|
||||
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set sceneClass %}{% call className scene %}{% endset %}
|
||||
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} protocol StoryboardType {
|
||||
static var storyboardName: String { get }
|
||||
}
|
||||
|
||||
{{accessModifier}} extension StoryboardType {
|
||||
static var storyboard: {{prefix}}Storyboard {
|
||||
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
|
||||
{% if param.lookupFunction %}
|
||||
return {{param.lookupFunction}}(name)
|
||||
{% else %}
|
||||
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||
{{accessModifier}} let identifier: String
|
||||
|
||||
{{accessModifier}} func instantiate() -> T {
|
||||
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
|
||||
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
|
||||
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
{% if isAppKit %}
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
{% else %}
|
||||
@available(iOS 13.0, tvOS 13.0, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
|
||||
{{accessModifier}} let storyboard: StoryboardType.Type
|
||||
|
||||
{{accessModifier}} func instantiate() -> T {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
|
||||
fatalError("{{controller}} is not of the expected class \(T.self).")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
{% if isAppKit %}
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
@available(macOS 10.15, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
{% else %}
|
||||
@available(iOS 13.0, tvOS 13.0, *)
|
||||
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
|
||||
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
|
||||
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
|
||||
}
|
||||
return controller
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% elif storyboards %}
|
||||
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||
{% else %}
|
||||
// No storyboard found
|
||||
{% endif %}
|
|
@ -0,0 +1,60 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if platform and storyboards %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||
// swiftlint:disable sorted_imports
|
||||
import Foundation
|
||||
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||
import {{module}}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Storyboard Segues
|
||||
|
||||
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
|
||||
{% for storyboard in storyboards where storyboard.segues %}
|
||||
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
|
||||
{% for segue in storyboard.segues %}
|
||||
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
|
||||
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} protocol SegueType: RawRepresentable {}
|
||||
|
||||
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
|
||||
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
|
||||
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
|
||||
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension SegueType where RawValue == String {
|
||||
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
|
||||
{% if isAppKit %}
|
||||
#if swift(>=4.2)
|
||||
guard let identifier = segue.identifier else { return nil }
|
||||
#else
|
||||
guard let identifier = segue.identifier?.rawValue else { return nil }
|
||||
#endif
|
||||
{% else %}
|
||||
guard let identifier = segue.identifier else { return nil }
|
||||
{% endif %}
|
||||
self.init(rawValue: identifier)
|
||||
}
|
||||
}
|
||||
{% elif storyboards %}
|
||||
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||
{% else %}
|
||||
// No storyboard found
|
||||
{% endif %}
|
|
@ -0,0 +1,60 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if platform and storyboards %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
|
||||
// swiftlint:disable sorted_imports
|
||||
import Foundation
|
||||
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
|
||||
import {{module}}
|
||||
{% endfor %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Storyboard Segues
|
||||
|
||||
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
|
||||
{% for storyboard in storyboards where storyboard.segues %}
|
||||
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
|
||||
{% for segue in storyboard.segues %}
|
||||
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
|
||||
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
{{accessModifier}} protocol SegueType: RawRepresentable {}
|
||||
|
||||
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
|
||||
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
|
||||
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
|
||||
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension SegueType where RawValue == String {
|
||||
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
|
||||
{% if isAppKit %}
|
||||
#if swift(>=4.2)
|
||||
guard let identifier = segue.identifier else { return nil }
|
||||
#else
|
||||
guard let identifier = segue.identifier?.rawValue else { return nil }
|
||||
#endif
|
||||
{% else %}
|
||||
guard let identifier = segue.identifier else { return nil }
|
||||
{% endif %}
|
||||
self.init(rawValue: identifier)
|
||||
}
|
||||
}
|
||||
{% elif storyboards %}
|
||||
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
|
||||
{% else %}
|
||||
// No storyboard found
|
||||
{% endif %}
|
|
@ -0,0 +1,82 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - JSON Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,82 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - JSON Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,112 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - JSON Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
|
||||
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
private func objectFromJSON<T>(at path: String) -> T {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
|
||||
let result = json as? T else {
|
||||
fatalError("Unable to load JSON at path: \(path)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private struct JSONDocument {
|
||||
let data: [String: Any]
|
||||
|
||||
init(path: String) {
|
||||
self.data = objectFromJSON(at: path)
|
||||
}
|
||||
|
||||
subscript<T>(key: String) -> T {
|
||||
guard let result = data[key] as? T else {
|
||||
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,112 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - JSON Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
|
||||
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
private func objectFromJSON<T>(at path: String) -> T {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
|
||||
let result = json as? T else {
|
||||
fatalError("Unable to load JSON at path: \(path)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private struct JSONDocument {
|
||||
let data: [String: Any]
|
||||
|
||||
init(path: String) {
|
||||
self.data = objectFromJSON(at: path)
|
||||
}
|
||||
|
||||
subscript<T>(key: String) -> T {
|
||||
guard let result = data[key] as? T else {
|
||||
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,82 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Plist Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Date" %}
|
||||
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,82 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Plist Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Date" %}
|
||||
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,117 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Plist Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
|
||||
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// Unsupported root type `{{rootType}}`
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
private func arrayFromPlist<T>(at path: String) -> [T] {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let data = NSArray(contentsOf: url) as? [T] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
private struct PlistDocument {
|
||||
let data: [String: Any]
|
||||
|
||||
init(path: String) {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
self.data = data
|
||||
}
|
||||
|
||||
subscript<T>(key: String) -> T {
|
||||
guard let result = data[key] as? T else {
|
||||
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,117 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - Plist Files
|
||||
{% macro fileBlock file %}
|
||||
{% call documentBlock file file.document %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
|
||||
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// Unsupported root type `{{rootType}}`
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro transformPath path %}{% filter removeNewlines %}
|
||||
{% if param.preservePath %}
|
||||
{{path}}
|
||||
{% else %}
|
||||
{{path|basename}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
private func arrayFromPlist<T>(at path: String) -> [T] {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let data = NSArray(contentsOf: url) as? [T] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
private struct PlistDocument {
|
||||
let data: [String: Any]
|
||||
|
||||
init(path: String) {
|
||||
{% if param.lookupFunction %}
|
||||
guard let url = {{param.lookupFunction}}(path),
|
||||
{% else %}
|
||||
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
|
||||
{% endif %}
|
||||
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
|
||||
fatalError("Unable to load PLIST at path: \(path)")
|
||||
}
|
||||
self.data = data
|
||||
}
|
||||
|
||||
subscript<T>(key: String) -> T {
|
||||
guard let result = data[key] as? T else {
|
||||
fatalError("Property '\(key)' is not of type \(T.self)")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,99 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Strings
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
_ p{{forloop.counter}}: Any
|
||||
{% else %}
|
||||
_ p{{forloop.counter}}: {{type}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
String(describing: p{{forloop.counter}})
|
||||
{% elif type == "UnsafeRawPointer" %}
|
||||
Int(bitPattern: p{{forloop.counter}})
|
||||
{% else %}
|
||||
p{{forloop.counter}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro recursiveBlock table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||
}
|
||||
{% elif param.lookupFunction %}
|
||||
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||
{% else %}
|
||||
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
{% call recursiveBlock table child %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
|
||||
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||
{% for table in tables %}
|
||||
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
extension {{enumName}} {
|
||||
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
{% if param.lookupFunction %}
|
||||
let format = {{ param.lookupFunction }}(key, table)
|
||||
{% else %}
|
||||
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||
{% endif %}
|
||||
return String(format: format, locale: Locale.current, arguments: args)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No string found
|
||||
{% endif %}
|
|
@ -0,0 +1,99 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Strings
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
_ p{{forloop.counter}}: Any
|
||||
{% else %}
|
||||
_ p{{forloop.counter}}: {{type}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
String(describing: p{{forloop.counter}})
|
||||
{% elif type == "UnsafeRawPointer" %}
|
||||
Int(bitPattern: p{{forloop.counter}})
|
||||
{% else %}
|
||||
p{{forloop.counter}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro recursiveBlock table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||
}
|
||||
{% elif param.lookupFunction %}
|
||||
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||
{% else %}
|
||||
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
{% call recursiveBlock table child %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
|
||||
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||
{% for table in tables %}
|
||||
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
extension {{enumName}} {
|
||||
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
{% if param.lookupFunction %}
|
||||
let format = {{ param.lookupFunction }}(key, table)
|
||||
{% else %}
|
||||
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||
{% endif %}
|
||||
return String(format: format, locale: Locale.current, arguments: args)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No string found
|
||||
{% endif %}
|
|
@ -0,0 +1,68 @@
|
|||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
p{{forloop.counter}}{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro paramTranslate swiftType %}
|
||||
{% if swiftType == "Any" %}
|
||||
id
|
||||
{% elif swiftType == "CChar" %}
|
||||
char
|
||||
{% elif swiftType == "Float" %}
|
||||
float
|
||||
{% elif swiftType == "Int" %}
|
||||
NSInteger
|
||||
{% elif swiftType == "String" %}
|
||||
id
|
||||
{% elif swiftType == "UnsafePointer<CChar>" %}
|
||||
char*
|
||||
{% elif swiftType == "UnsafeRawPointer" %}
|
||||
void*
|
||||
{% else %}
|
||||
objc-h.stencil is missing '{{swiftType}}'
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro emitOneMethod table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{% if string.types.count == 1 %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %};
|
||||
{% else %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %};
|
||||
{% endif %}
|
||||
{% else %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
{% call emitOneMethod table child %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% for table in tables %}
|
||||
@interface {{ table.name }} : NSObject
|
||||
{% call emitOneMethod table.name table.levels %}
|
||||
@end
|
||||
|
||||
{% endfor %}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
{% else %}
|
||||
// No strings found
|
||||
{% endif %}
|
|
@ -0,0 +1,90 @@
|
|||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
#import "{{ param.headerName|default:"Localizable.h" }}"
|
||||
{% if not param.bundle %}
|
||||
|
||||
@interface BundleToken : NSObject
|
||||
@end
|
||||
|
||||
@implementation BundleToken
|
||||
@end
|
||||
{% endif %}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wformat-security"
|
||||
|
||||
static NSString* tr(NSString *tableName, NSString *key, ...) {
|
||||
NSBundle *bundle = {{param.bundle|default:"[NSBundle bundleForClass:BundleToken.class]"}};
|
||||
NSString *format = [bundle localizedStringForKey:key value:nil table:tableName];
|
||||
NSLocale *locale = [NSLocale currentLocale];
|
||||
|
||||
va_list args;
|
||||
va_start(args, key);
|
||||
NSString *result = [[NSString alloc] initWithFormat:format locale:locale arguments:args];
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
};
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
p{{forloop.counter}}{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro paramTranslate swiftType %}
|
||||
{% if swiftType == "Any" %}
|
||||
id
|
||||
{% elif swiftType == "CChar" %}
|
||||
char
|
||||
{% elif swiftType == "Float" %}
|
||||
float
|
||||
{% elif swiftType == "Int" %}
|
||||
NSInteger
|
||||
{% elif swiftType == "String" %}
|
||||
id
|
||||
{% elif swiftType == "UnsafePointer<CChar>" %}
|
||||
char*
|
||||
{% elif swiftType == "UnsafeRawPointer" %}
|
||||
void*
|
||||
{% else %}
|
||||
objc-m.stencil is missing '{{swiftType}}'
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro tableContents table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if string.types %}
|
||||
{% if string.types.count == 1 %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %}
|
||||
{% else %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %}
|
||||
{% endif %}
|
||||
{
|
||||
return tr(@"{{table}}", @"{{string.key}}", {% call argumentsBlock string.types %});
|
||||
}
|
||||
{% else %}
|
||||
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}} {
|
||||
return tr(@"{{table}}", @"{{string.key}}");
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
{% call tableContents table child %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% for table in tables %}
|
||||
{% set tableName %}{{table.name|default:"Localized"}}{% endset %}
|
||||
@implementation {{ tableName }} : NSObject
|
||||
{% call tableContents table.name table.levels %}
|
||||
@end
|
||||
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// No strings found
|
||||
{% endif %}
|
|
@ -0,0 +1,104 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Strings
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
_ p{{forloop.counter}}: Any
|
||||
{% else %}
|
||||
_ p{{forloop.counter}}: {{type}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
String(describing: p{{forloop.counter}})
|
||||
{% elif type == "UnsafeRawPointer" %}
|
||||
Int(bitPattern: p{{forloop.counter}})
|
||||
{% else %}
|
||||
p{{forloop.counter}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro recursiveBlock table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||
}
|
||||
{% elif param.lookupFunction %}
|
||||
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||
{% else %}
|
||||
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
|
||||
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||
{% for table in tables %}
|
||||
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
extension {{enumName}} {
|
||||
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
{% if param.lookupFunction %}
|
||||
let format = {{ param.lookupFunction }}(key, table)
|
||||
{% else %}
|
||||
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||
{% endif %}
|
||||
return String(format: format, locale: Locale.current, arguments: args)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No string found
|
||||
{% endif %}
|
|
@ -0,0 +1,104 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Strings
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
_ p{{forloop.counter}}: Any
|
||||
{% else %}
|
||||
_ p{{forloop.counter}}: {{type}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
String(describing: p{{forloop.counter}})
|
||||
{% elif type == "UnsafeRawPointer" %}
|
||||
Int(bitPattern: p{{forloop.counter}})
|
||||
{% else %}
|
||||
p{{forloop.counter}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro recursiveBlock table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||
}
|
||||
{% elif param.lookupFunction %}
|
||||
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
|
||||
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||
{% else %}
|
||||
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
|
||||
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||
{% for table in tables %}
|
||||
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
extension {{enumName}} {
|
||||
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
{% if param.lookupFunction %}
|
||||
let format = {{ param.lookupFunction }}(key, table)
|
||||
{% else %}
|
||||
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
|
||||
{% endif %}
|
||||
return String(format: format, locale: Locale.current, arguments: args)
|
||||
}
|
||||
}
|
||||
{% if not param.bundle and not param.lookupFunction %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No string found
|
||||
{% endif %}
|
|
@ -0,0 +1,329 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if catalogs %}
|
||||
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
|
||||
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
|
||||
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
|
||||
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
|
||||
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
|
||||
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
|
||||
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#elseif os(iOS)
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
import ARKit
|
||||
{% endif %}
|
||||
import UIKit
|
||||
#elseif os(tvOS) || os(watchOS)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
// Deprecated typealiases
|
||||
{% if resourceCount.color > 0 %}
|
||||
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
|
||||
{% endif %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Asset Catalogs
|
||||
|
||||
{% macro enumBlock assets %}
|
||||
{% call casesBlock assets %}
|
||||
{% if param.allValues %}
|
||||
|
||||
// swiftlint:disable trailing_comma
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.color > 0 %}
|
||||
{{accessModifier}} static let allColors: [{{colorType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.data > 0 %}
|
||||
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
{{accessModifier}} static let allImages: [{{imageType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.symbol > 0 %}
|
||||
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
// swiftlint:enable trailing_comma
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro casesBlock assets %}
|
||||
{% for asset in assets %}
|
||||
{% if asset.type == "arresourcegroup" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "color" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "data" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "image" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "symbol" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
|
||||
{% 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 %}
|
||||
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if catalogs.count > 1 or param.forceFileNameEnum %}
|
||||
{% 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 %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{arResourceGroupType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(iOS)
|
||||
@available(iOS 11.3, *)
|
||||
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
|
||||
return ARReferenceImage.referenceImages(in: self)
|
||||
}
|
||||
|
||||
@available(iOS 12.0, *)
|
||||
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
|
||||
return ARReferenceObject.referenceObjects(in: self)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
@available(iOS 11.3, *)
|
||||
{{accessModifier}} extension ARReferenceImage {
|
||||
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 12.0, *)
|
||||
{{accessModifier}} extension ARReferenceObject {
|
||||
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{% endif %}
|
||||
{% if resourceCount.color > 0 %}
|
||||
|
||||
{{accessModifier}} final class {{colorType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Color = NSColor
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Color = UIColor
|
||||
#endif
|
||||
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||
{{accessModifier}} private(set) lazy var color: Color = Color(asset: self)
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
@available(iOS 11.0, tvOS 11.0, *)
|
||||
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||
fatalError("Unable to load color asset named \(name).")
|
||||
}
|
||||
return color
|
||||
}
|
||||
#endif
|
||||
|
||||
fileprivate init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{colorType}}.Color {
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||
convenience init!(asset: {{colorType}}) {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
self.init(named: NSColor.Name(asset.name), bundle: bundle)
|
||||
#elseif os(watchOS)
|
||||
self.init(named: asset.name)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.data > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{dataType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||
{{accessModifier}} var data: NSDataAsset {
|
||||
return NSDataAsset(asset: self)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||
{{accessModifier}} extension NSDataAsset {
|
||||
convenience init!(asset: {{dataType}}) {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
self.init(name: asset.name, bundle: bundle)
|
||||
#elseif os(macOS)
|
||||
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{imageType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Image = NSImage
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Image = UIImage
|
||||
#endif
|
||||
|
||||
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
|
||||
{{accessModifier}} var image: Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let name = NSImage.Name(self.name)
|
||||
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
@available(iOS 8.0, tvOS 9.0, *)
|
||||
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{imageType}}.Image {
|
||||
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
|
||||
@available(macOS, deprecated,
|
||||
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
|
||||
convenience init!(asset: {{imageType}}) {
|
||||
#if os(iOS) || os(tvOS)
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
self.init(named: NSImage.Name(asset.name))
|
||||
#elseif os(watchOS)
|
||||
self.init(named: asset.name)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.symbol > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{symbolType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
|
||||
{{accessModifier}} typealias Image = UIImage
|
||||
|
||||
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
|
||||
{{accessModifier}} var image: Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load symbol asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
{{accessModifier}} func image(with configuration: Configuration) -> Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let result = Image(named: name, in: bundle, with: configuration) else {
|
||||
fatalError("Unable to load symbol asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{% endif %}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No assets found
|
||||
{% endif %}
|
|
@ -0,0 +1,337 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if catalogs %}
|
||||
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
|
||||
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
|
||||
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
|
||||
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
|
||||
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
|
||||
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
|
||||
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#elseif os(iOS)
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
import ARKit
|
||||
{% endif %}
|
||||
import UIKit
|
||||
#elseif os(tvOS) || os(watchOS)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
// Deprecated typealiases
|
||||
{% if resourceCount.color > 0 %}
|
||||
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
|
||||
{% endif %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Asset Catalogs
|
||||
|
||||
{% macro enumBlock assets %}
|
||||
{% call casesBlock assets %}
|
||||
{% if param.allValues %}
|
||||
|
||||
// swiftlint:disable trailing_comma
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.color > 0 %}
|
||||
{{accessModifier}} static let allColors: [{{colorType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.data > 0 %}
|
||||
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
{{accessModifier}} static let allImages: [{{imageType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
{% if resourceCount.symbol > 0 %}
|
||||
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
|
||||
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
|
||||
]
|
||||
{% endif %}
|
||||
// swiftlint:enable trailing_comma
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro casesBlock assets %}
|
||||
{% for asset in assets %}
|
||||
{% if asset.type == "arresourcegroup" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "color" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "data" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "image" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
|
||||
{% elif asset.type == "symbol" %}
|
||||
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
|
||||
{% 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 %}
|
||||
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if catalogs.count > 1 or param.forceFileNameEnum %}
|
||||
{% 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 %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
|
||||
|
||||
// MARK: - Implementation Details
|
||||
{% if resourceCount.arresourcegroup > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{arResourceGroupType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(iOS)
|
||||
@available(iOS 11.3, *)
|
||||
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
|
||||
return ARReferenceImage.referenceImages(in: self)
|
||||
}
|
||||
|
||||
@available(iOS 12.0, *)
|
||||
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
|
||||
return ARReferenceObject.referenceObjects(in: self)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
@available(iOS 11.3, *)
|
||||
{{accessModifier}} extension ARReferenceImage {
|
||||
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 12.0, *)
|
||||
{{accessModifier}} extension ARReferenceObject {
|
||||
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{% endif %}
|
||||
{% if resourceCount.color > 0 %}
|
||||
|
||||
{{accessModifier}} final class {{colorType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Color = NSColor
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Color = UIColor
|
||||
#endif
|
||||
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||
{{accessModifier}} private(set) lazy var color: Color = {
|
||||
guard let color = Color(asset: self) else {
|
||||
fatalError("Unable to load color asset named \(name).")
|
||||
}
|
||||
return color
|
||||
}()
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
@available(iOS 11.0, tvOS 11.0, *)
|
||||
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||
fatalError("Unable to load color asset named \(name).")
|
||||
}
|
||||
return color
|
||||
}
|
||||
#endif
|
||||
|
||||
fileprivate init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{colorType}}.Color {
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
|
||||
convenience init?(asset: {{colorType}}) {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
self.init(named: NSColor.Name(asset.name), bundle: bundle)
|
||||
#elseif os(watchOS)
|
||||
self.init(named: asset.name)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.data > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{dataType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||
{{accessModifier}} var data: NSDataAsset {
|
||||
guard let data = NSDataAsset(asset: self) else {
|
||||
fatalError("Unable to load data asset named \(name).")
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
|
||||
{{accessModifier}} extension NSDataAsset {
|
||||
convenience init?(asset: {{dataType}}) {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
self.init(name: asset.name, bundle: bundle)
|
||||
#elseif os(macOS)
|
||||
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{imageType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Image = NSImage
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Image = UIImage
|
||||
#endif
|
||||
|
||||
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
|
||||
{{accessModifier}} var image: Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let name = NSImage.Name(self.name)
|
||||
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
@available(iOS 8.0, tvOS 9.0, *)
|
||||
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{imageType}}.Image {
|
||||
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
|
||||
@available(macOS, deprecated,
|
||||
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
|
||||
convenience init?(asset: {{imageType}}) {
|
||||
#if os(iOS) || os(tvOS)
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
self.init(named: NSImage.Name(asset.name))
|
||||
#elseif os(watchOS)
|
||||
self.init(named: asset.name)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% if resourceCount.symbol > 0 %}
|
||||
|
||||
{{accessModifier}} struct {{symbolType}} {
|
||||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(iOS) || os(tvOS) || os(watchOS)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
|
||||
{{accessModifier}} typealias Image = UIImage
|
||||
|
||||
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
|
||||
{{accessModifier}} var image: Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load symbol asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
{{accessModifier}} func image(with configuration: Configuration) -> Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
guard let result = Image(named: name, in: bundle, with: configuration) else {
|
||||
fatalError("Unable to load symbol asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
{% endif %}
|
||||
{% if not param.bundle %}
|
||||
|
||||
// swiftlint:disable convenience_type
|
||||
private final class BundleToken {
|
||||
static let bundle: Bundle = {
|
||||
#if SWIFT_PACKAGE
|
||||
return Bundle.module
|
||||
#else
|
||||
return Bundle(for: BundleToken.self)
|
||||
#endif
|
||||
}()
|
||||
}
|
||||
// swiftlint:enable convenience_type
|
||||
{% endif %}
|
||||
{% else %}
|
||||
// No assets found
|
||||
{% endif %}
|
|
@ -0,0 +1,92 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - YAML Files
|
||||
{% macro fileBlock file %}
|
||||
{% if file.documents.count > 1 %}
|
||||
{% for document in file.documents %}
|
||||
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
|
||||
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call documentBlock file file.documents.first %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
|
@ -0,0 +1,92 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if files %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command
|
||||
// swiftlint:disable file_length
|
||||
|
||||
// MARK: - YAML Files
|
||||
{% macro fileBlock file %}
|
||||
{% if file.documents.count > 1 %}
|
||||
{% for document in file.documents %}
|
||||
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
|
||||
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call documentBlock file file.documents.first %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro documentBlock file document %}
|
||||
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
|
||||
{% if document.metadata.type == "Array" %}
|
||||
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% elif document.metadata.type == "Dictionary" %}
|
||||
{% for key,value in document.metadata.properties %}
|
||||
{{accessModifier}} {% call propertyBlock key value document.data %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "Array" %}
|
||||
[{% call typeBlock metadata.element %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[String: Any]
|
||||
{% elif metadata.type == "Optional" %}
|
||||
Any?
|
||||
{% else %}
|
||||
{{metadata.type}}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
|
||||
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
|
||||
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
|
||||
{% if metadata.type == "String" %}
|
||||
"{{ value }}"
|
||||
{% elif metadata.type == "Optional" %}
|
||||
nil
|
||||
{% elif metadata.type == "Array" and value %}
|
||||
[{% for value in value %}
|
||||
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Dictionary" %}
|
||||
[{% for key,value in value %}
|
||||
"{{key}}": {% call valueBlock value metadata.properties[key] %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% empty %}
|
||||
:
|
||||
{% endfor %}]
|
||||
{% elif metadata.type == "Bool" %}
|
||||
{% if value %}true{% else %}false{% endif %}
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
|
||||
// swiftlint:disable identifier_name line_length number_separator type_body_length
|
||||
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
|
||||
{% if files.count > 1 or param.forceFileNameEnum %}
|
||||
{% for file in files %}
|
||||
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call fileBlock files.first %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length number_separator type_body_length
|
||||
{% else %}
|
||||
// No files found
|
||||
{% endif %}
|
BIN
.swiftgen/bin/swiftgen
Executable file
BIN
.swiftgen/bin/swiftgen
Executable file
Binary file not shown.
29
.swiftgen/templates/fonts.stencil
Normal file
29
.swiftgen/templates/fonts.stencil
Normal file
|
@ -0,0 +1,29 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if families %}
|
||||
import SwiftUI
|
||||
{% for family in families %}
|
||||
{% set identifierName %}{{family.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
|
||||
{% set styleTypeName %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}Style{% endset %}
|
||||
|
||||
extension Font {
|
||||
public static func {{identifierName}}(_ style: {{styleTypeName}}, fixedSize: CGFloat) -> Font {
|
||||
return Font.custom(style.rawValue, fixedSize: fixedSize)
|
||||
}
|
||||
|
||||
public static func {{identifierName}}(_ style: {{styleTypeName}}, size: CGFloat, relativeTo textStyle: TextStyle = .body) -> Font {
|
||||
return Font.custom(style.rawValue, size: size, relativeTo: textStyle)
|
||||
}
|
||||
|
||||
public enum {{styleTypeName}}: String {
|
||||
{% for font in family.fonts %}
|
||||
case {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = "{{font.name}}"
|
||||
{% endfor %}
|
||||
}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// No fonts found
|
||||
{% endif %}
|
||||
|
84
.swiftgen/templates/strings.stencil
Normal file
84
.swiftgen/templates/strings.stencil
Normal file
|
@ -0,0 +1,84 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if tables.count > 0 %}
|
||||
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
// MARK: - Strings
|
||||
|
||||
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
_ p{{forloop.counter}}: Any
|
||||
{% else %}
|
||||
_ p{{forloop.counter}}: {{type}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
|
||||
{% for type in types %}
|
||||
{% if type == "String" %}
|
||||
String(describing: p{{forloop.counter}})
|
||||
{% elif type == "UnsafeRawPointer" %}
|
||||
Int(bitPattern: p{{forloop.counter}})
|
||||
{% else %}
|
||||
p{{forloop.counter}}
|
||||
{% endif %}
|
||||
{{ ", " if not forloop.last }}
|
||||
{% endfor %}
|
||||
{% endfilter %}{% endmacro %}
|
||||
{% macro recursiveBlock table item %}
|
||||
{% for string in item.strings %}
|
||||
{% if not param.noComments %}
|
||||
{% for line in string.translation|split:"\n" %}
|
||||
/// {{line}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if string.types %}
|
||||
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
|
||||
{{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
|
||||
}
|
||||
{% else %}
|
||||
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { {{enumName}}.tr("{{table}}", "{{string.key}}") }
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for child in item.children %}
|
||||
|
||||
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
|
||||
{{accessModifier}} enum {{enumName}} {
|
||||
{% if tables.count > 1 or param.forceFileNameEnum %}
|
||||
{% for table in tables %}
|
||||
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% call recursiveBlock tables.first.name tables.first.levels %}
|
||||
{% endif %}
|
||||
}
|
||||
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
|
||||
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
|
||||
|
||||
// MARK: - Implementation Details
|
||||
import Localize_Swift
|
||||
extension {{enumName}} {
|
||||
static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
let selectedLanguage = Localize.currentLanguage()
|
||||
guard let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj"),
|
||||
let bundle = Bundle(path: path) else { return "Setup language error" }
|
||||
return NSLocalizedString(key, tableName: table, bundle: bundle, comment: "")
|
||||
}
|
||||
}
|
||||
|
||||
{% endif %}
|
47
.swiftgen/templates/xcassets.stencil
Normal file
47
.swiftgen/templates/xcassets.stencil
Normal file
|
@ -0,0 +1,47 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if catalogs %}
|
||||
import SwiftUI
|
||||
{% macro casesBlock assets %}
|
||||
{% for asset in assets %}
|
||||
{% if asset.items and asset.isNamespaced == "true" %}
|
||||
public enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
|
||||
}
|
||||
{% elif asset.items %}
|
||||
{% call casesBlock asset.items %}
|
||||
{% elif asset.type == "color" %}
|
||||
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = Color("{{asset.value}}")
|
||||
{% elif asset.type == "image" %}
|
||||
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = Image("{{asset.value}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Colors" %}
|
||||
|
||||
extension Color {
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Colors" %}
|
||||
{% call casesBlock catalog.assets %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Images" %}
|
||||
|
||||
extension Image {
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Images" %}
|
||||
{% call casesBlock catalog.assets %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// No assets found
|
||||
{% endif %}
|
35
.swiftgen/templates/xcassets_strings.stencil
Normal file
35
.swiftgen/templates/xcassets_strings.stencil
Normal file
|
@ -0,0 +1,35 @@
|
|||
// swiftlint:disable all
|
||||
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
|
||||
|
||||
{% if catalogs %}
|
||||
import Foundation
|
||||
|
||||
typealias AssetStrings = String
|
||||
{% macro casesBlock assets %}
|
||||
{% for asset in assets %}
|
||||
{% if asset.items and asset.isNamespaced == "true" %}
|
||||
public enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
|
||||
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
|
||||
}
|
||||
{% elif asset.items %}
|
||||
{% call casesBlock asset.items %}
|
||||
{% elif asset.type == "image" %}
|
||||
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = String("{{asset.value}}")
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Images" %}
|
||||
|
||||
extension String {
|
||||
{% for catalog in catalogs %}
|
||||
{% if catalog.name == "Images" %}
|
||||
{% call casesBlock catalog.assets %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
// No assets found
|
||||
{% endif %}
|
116
.swiftlint.yml
Normal file
116
.swiftlint.yml
Normal file
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
colon:
|
||||
severity: error
|
||||
|
||||
line_length:
|
||||
ignores_comments: true
|
||||
warning: 260
|
||||
error: 300
|
||||
|
||||
type_body_length:
|
||||
warning: 300
|
||||
error: 500
|
||||
|
||||
file_length:
|
||||
warning: 800
|
||||
error: 1000
|
||||
|
||||
function_parameter_count:
|
||||
warning: 20
|
||||
error: 30
|
||||
|
||||
function_body_length:
|
||||
warning: 120
|
||||
error: 150
|
||||
|
||||
cyclomatic_complexity:
|
||||
warning: 40
|
||||
error: 50
|
||||
|
||||
nesting:
|
||||
type_level:
|
||||
warning: 3
|
||||
error: 6
|
||||
function_level:
|
||||
warning: 5
|
||||
error: 10
|
||||
|
||||
vertical_parameter_alignment:
|
||||
severity: warning
|
||||
|
||||
implicitly_unwrapped_optional:
|
||||
severity: warning
|
||||
|
||||
force_unwrapping:
|
||||
severity: error
|
||||
|
||||
vertical_whitespace:
|
||||
severity: error
|
||||
|
||||
force_try:
|
||||
severity: error
|
||||
|
||||
trailing_semicolon:
|
||||
severity: error
|
||||
|
||||
type_name:
|
||||
min_length: 3
|
||||
max_length: 60
|
||||
error: 80
|
||||
|
||||
identifier_name:
|
||||
min_length: 3
|
||||
max_length: 60
|
||||
validates_start_with_lowercase: true
|
||||
allowed_symbols: "_"
|
||||
excluded:
|
||||
- iv
|
||||
- id
|
||||
- ip
|
||||
- on
|
||||
- ui
|
||||
- x
|
||||
- y
|
||||
- tz
|
||||
- to
|
||||
|
||||
# Disable rules from the default enabled set.
|
||||
disabled_rules:
|
||||
- trailing_whitespace
|
||||
- implicit_getter
|
||||
- redundant_string_enum_value
|
||||
- switch_case_alignment
|
||||
|
||||
# Enable rules not from the default set.
|
||||
opt_in_rules:
|
||||
# - function_default_parameter_at_end
|
||||
- empty_count
|
||||
- indentation_width
|
||||
# - index_at_zero
|
||||
- legacy_constant
|
||||
# - implicitly_unwrapped_optional
|
||||
- force_unwrapping
|
||||
# - no header
|
||||
- file_header
|
||||
# - for force unwrapping
|
||||
- implicitly_unwrapped_optional
|
||||
- vertical_parameter_alignment_on_call
|
||||
- vertical_whitespace_between_cases
|
||||
- vertical_whitespace_closing_braces
|
||||
- vertical_whitespace_opening_braces
|
||||
|
||||
# Acts as a whitelist, only the rules specified in this list will be enabled. Can not be specified alongside disabled_rules or opt_in_rules.
|
||||
only_rules:
|
||||
|
||||
# This is an entirely separate list of rules that are only run by the analyze command. All analyzer rules are opt-in, so this is the only configurable rule list (there is no disabled/whitelist equivalent).
|
||||
analyzer_rules:
|
||||
- unused_import
|
||||
- unused_declaration
|
||||
|
||||
unused_declaration:
|
||||
include_public_and_open: true
|
||||
|
||||
# paths to ignore during linting. Takes precedence over `included`.
|
||||
excluded:
|
||||
- Snikket/Generated
|
||||
- old
|
|
@ -1 +0,0 @@
|
|||
|
9
Packages/Engine/.gitignore
vendored
Normal file
9
Packages/Engine/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/config/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
50
Packages/Engine/Package.resolved
Normal file
50
Packages/Engine/Package.resolved
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "libsignal",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tigase/libsignal",
|
||||
"state" : {
|
||||
"revision" : "d23d5af0d729cf66b93cea607f3f84a34b9fddfd",
|
||||
"version" : "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "martin",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tigase/Martin",
|
||||
"state" : {
|
||||
"revision" : "1d70e9e7eb51a7faa500832be6400a39f86083f7",
|
||||
"version" : "3.2.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "martinomemo",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tigase/MartinOMEMO.git",
|
||||
"state" : {
|
||||
"revision" : "3c162154d646aa258c9a86c0a07655a536e55a94",
|
||||
"version" : "2.2.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite.swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/stephencelis/SQLite.swift.git",
|
||||
"state" : {
|
||||
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb",
|
||||
"version" : "0.14.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "tigase-logging.swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/tigase/tigase-logging.swift",
|
||||
"state" : {
|
||||
"revision" : "382e2e85e64f8b1e3fcb71a996a030bf1b62ecb3",
|
||||
"version" : "1.0.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
22
Packages/Engine/Package.swift
Normal file
22
Packages/Engine/Package.swift
Normal file
|
@ -0,0 +1,22 @@
|
|||
// swift-tools-version: 5.8
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Engine",
|
||||
products: [
|
||||
.library(
|
||||
name: "Engine",
|
||||
targets: ["Engine"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.0"),
|
||||
.package(url: "https://github.com/tigase/MartinOMEMO.git", from: "2.0.0")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Engine",
|
||||
dependencies: []),
|
||||
]
|
||||
)
|
||||
|
3
Packages/Engine/README.md
Normal file
3
Packages/Engine/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Engine
|
||||
|
||||
Database and Tigase Martin XMPP wrapper for app.
|
10
Packages/Engine/Sources/Engine/Engine.swift
Normal file
10
Packages/Engine/Sources/Engine/Engine.swift
Normal file
|
@ -0,0 +1,10 @@
|
|||
public struct Engine {
|
||||
public private(set) var text = "Hello, World!"
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func testme() {
|
||||
print("test done!")
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// NotificationCategory.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2019 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum NotificationCategory: String {
|
||||
case UNKNOWN
|
||||
case ERROR
|
||||
case MESSAGE
|
||||
case SUBSCRIPTION_REQUEST
|
||||
case MUC_ROOM_INVITATION
|
||||
case CALL
|
||||
case UNSENT_MESSAGES
|
||||
|
||||
public static func from(identifier: String?) -> NotificationCategory {
|
||||
guard let str = identifier else {
|
||||
return .UNKNOWN;
|
||||
}
|
||||
return NotificationCategory(rawValue: str) ?? .UNKNOWN;
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
//
|
||||
// DBConnection_main.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2019 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension DBConnection {
|
||||
|
||||
public static func mainDbURL() -> URL {
|
||||
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.snikket.shared")!;
|
||||
return containerURL.appendingPathComponent("snikket_main.db");
|
||||
}
|
||||
|
||||
public private(set) static var createIfNotExist: Bool = false;
|
||||
|
||||
public static func migrateToGroupIfNeeded() throws {
|
||||
let dbURL = mainDbURL();
|
||||
|
||||
if !FileManager.default.fileExists(atPath: dbURL.path) {
|
||||
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true);
|
||||
let documentDirectory = paths[0];
|
||||
let path = documentDirectory.appending("/mobile_messenger1.db");
|
||||
if FileManager.default.fileExists(atPath: path) {
|
||||
try FileManager.default.moveItem(atPath: path, toPath: dbURL.path);
|
||||
}
|
||||
}
|
||||
|
||||
createIfNotExist = true;
|
||||
}
|
||||
|
||||
public static func initialize(dbPath: String) throws -> DBConnection {
|
||||
let conn = try DBConnection(dbPath: dbPath);
|
||||
try? conn.execute("PRAGMA busy_timeout = 2")
|
||||
try DBSchemaManager(dbConnection: conn).upgradeSchema();
|
||||
return conn;
|
||||
}
|
||||
}
|
|
@ -1,590 +0,0 @@
|
|||
//
|
||||
// DBManager.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2016 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import TigaseSwift
|
||||
import SQLite3
|
||||
|
||||
let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
|
||||
|
||||
open class DBConnection {
|
||||
|
||||
fileprivate var handle_:OpaquePointer? = nil;
|
||||
open var handle:OpaquePointer {
|
||||
get {
|
||||
return handle_!;
|
||||
}
|
||||
}
|
||||
|
||||
public let dispatcher: QueueDispatcher;
|
||||
|
||||
open var lastInsertRowId: Int? {
|
||||
let rowid = sqlite3_last_insert_rowid(handle);
|
||||
return rowid > 0 ? Int(rowid) : nil;
|
||||
}
|
||||
|
||||
open var changesCount: Int {
|
||||
return Int(sqlite3_changes(handle));
|
||||
}
|
||||
|
||||
convenience public init(dbUrl: URL) throws {
|
||||
try self.init(dbPath: dbUrl.path);
|
||||
}
|
||||
|
||||
public init(dbPath: String) throws {
|
||||
dispatcher = QueueDispatcher(label: "db_queue");
|
||||
try dispatcher.sync {
|
||||
let flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
|
||||
|
||||
_ = try self.check(sqlite3_open_v2(dbPath, &self.handle_, flags | SQLITE_OPEN_FULLMUTEX, nil));
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
sqlite3_close(handle);
|
||||
}
|
||||
|
||||
open func execute(_ query: String) throws {
|
||||
try dispatcher.sync {
|
||||
_ = try self.check(sqlite3_exec(self.handle, query, nil, nil, nil));
|
||||
}
|
||||
}
|
||||
|
||||
open func prepareStatement(_ query: String) throws -> DBStatement {
|
||||
return try dispatcher.sync {
|
||||
return try DBStatement(connection: self, query: query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate func check(_ result:Int32, statement:DBStatement? = nil) throws -> Int32 {
|
||||
guard let error = DBResult(errorCode: result, connection: self, statement: statement) else {
|
||||
return result;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum DBResult: Error {
|
||||
|
||||
fileprivate static let successCodes = [ SQLITE_OK, SQLITE_ROW, SQLITE_DONE ];
|
||||
|
||||
case error(message:String, code: Int32, statement:DBStatement?)
|
||||
|
||||
init?(errorCode: Int32, connection: DBConnection, statement:DBStatement?) {
|
||||
guard !DBResult.successCodes.contains(errorCode) else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
let tmp = sqlite3_errmsg(connection.handle);
|
||||
let message = String(cString: tmp!);
|
||||
self = .error(message: message, code: errorCode, statement: statement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class DBStatement {
|
||||
|
||||
fileprivate var handle:OpaquePointer? = nil;
|
||||
fileprivate let connection:DBConnection;
|
||||
|
||||
open lazy var columnCount:Int = Int(sqlite3_column_count(self.handle));
|
||||
|
||||
open lazy var columnNames:[String] = (0..<Int32(self.columnCount)).map { (idx:Int32) -> String in
|
||||
return String(cString: sqlite3_column_name(self.handle, idx)!);
|
||||
}
|
||||
|
||||
open lazy var cursor:DBCursor = DBCursor(statement: self);
|
||||
|
||||
public let dispatcher: QueueDispatcher;
|
||||
|
||||
open var lastInsertRowId: Int? {
|
||||
return connection.lastInsertRowId;
|
||||
}
|
||||
|
||||
open var changesCount: Int {
|
||||
return connection.changesCount;
|
||||
}
|
||||
|
||||
init(connection:DBConnection, query:String, dispatcher: QueueDispatcher = QueueDispatcher(label: "DBStatementDispatcher")) throws {
|
||||
self.connection = connection;
|
||||
self.dispatcher = dispatcher;
|
||||
_ = try connection.check(sqlite3_prepare_v2(connection.handle, query, -1, &handle, nil));
|
||||
}
|
||||
|
||||
deinit {
|
||||
sqlite3_finalize(handle);
|
||||
}
|
||||
|
||||
fileprivate func step(_ expect: Int32 = SQLITE_ROW) throws -> Bool {
|
||||
return try connection.dispatcher.sync() {
|
||||
let result = try self.connection.check(sqlite3_step(self.handle));
|
||||
return result == expect;
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func bind(_ params:Any?...) throws -> DBStatement {
|
||||
_ = try bind(params);
|
||||
return self;
|
||||
}
|
||||
|
||||
fileprivate func bind(_ params:[String:Any?]) throws -> DBStatement {
|
||||
reset()
|
||||
for (k,v) in params {
|
||||
let pos = sqlite3_bind_parameter_index(handle, ":"+k);
|
||||
if pos == 0 {
|
||||
print("got pos = 0, while parameter count = ", sqlite3_bind_parameter_count(handle));
|
||||
}
|
||||
try bind(v, pos: pos);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
fileprivate func bind(_ params:[Any?]) throws -> DBStatement {
|
||||
reset()
|
||||
for pos in 1...params.count {
|
||||
_ = try bind(params[pos-1], atIndex: pos);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
fileprivate func bind(_ value:Any?, atIndex:Int) throws -> DBStatement {
|
||||
try bind(value, pos: Int32(atIndex));
|
||||
return self;
|
||||
}
|
||||
|
||||
fileprivate func bind(_ value_:Any?, pos:Int32) throws {
|
||||
var r:Int32 = SQLITE_OK;
|
||||
if value_ == nil {
|
||||
r = sqlite3_bind_null(handle, pos);
|
||||
} else if let value:Any = value_ {
|
||||
switch value {
|
||||
case let v as [UInt8]:
|
||||
r = sqlite3_bind_blob(handle, pos, v, Int32(v.count), SQLITE_TRANSIENT);
|
||||
case let v as Data:
|
||||
r = v.withUnsafeBytes() { (bytes) -> Int32 in
|
||||
return sqlite3_bind_blob(handle, pos, bytes.baseAddress!, Int32(v.count), SQLITE_TRANSIENT);
|
||||
}
|
||||
case let v as Double:
|
||||
r = sqlite3_bind_double(handle, pos, v);
|
||||
case let v as UInt32:
|
||||
r = sqlite3_bind_int(handle, pos, Int32(bitPattern: v));
|
||||
case let v as Int32:
|
||||
r = sqlite3_bind_int(handle, pos, v);
|
||||
case let v as Int:
|
||||
r = sqlite3_bind_int64(handle, pos, Int64(v));
|
||||
case let v as Bool:
|
||||
r = sqlite3_bind_int(handle, pos, Int32(v ? 1 : 0));
|
||||
case let v as String:
|
||||
r = sqlite3_bind_text(handle, pos, v, -1, SQLITE_TRANSIENT);
|
||||
case let v as Date:
|
||||
let timestamp = Int64(v.timeIntervalSince1970 * 1000);
|
||||
r = sqlite3_bind_int64(handle, pos, timestamp);
|
||||
case let v as StringValue:
|
||||
r = sqlite3_bind_text(handle, pos, v.stringValue, -1, SQLITE_TRANSIENT);
|
||||
default:
|
||||
throw DBResult.error(message: "Unsupported type \(value.self) for parameter \(pos)", code: SQLITE_FAIL, statement: self);
|
||||
}
|
||||
} else {
|
||||
sqlite3_bind_null(handle, pos)
|
||||
}
|
||||
_ = try check(r);
|
||||
}
|
||||
|
||||
fileprivate func execute(_ params:[String:Any?]) throws -> DBStatement? {
|
||||
_ = try bind(params);
|
||||
return try execute();
|
||||
}
|
||||
|
||||
fileprivate func execute(_ params:Any?...) throws -> DBStatement? {
|
||||
return try execute(params);
|
||||
}
|
||||
|
||||
fileprivate func execute(_ params:[Any?]) throws -> DBStatement? {
|
||||
if params.count > 0 {
|
||||
_ = try bind(params);
|
||||
}
|
||||
reset(false);
|
||||
return try step() ? self : nil;
|
||||
}
|
||||
|
||||
// open func query(_ params:[String:Any?]) throws -> DBCursor? {
|
||||
// return try execute(params)?.cursor;
|
||||
// }
|
||||
//
|
||||
// open func query(_ params:Any?...) throws -> DBCursor? {
|
||||
// return try execute(params)?.cursor;
|
||||
// }
|
||||
|
||||
open func findFirst<T>(_ params: [String:Any?], map: (DBCursor)-> T?) throws -> T? {
|
||||
return try dispatcher.sync {
|
||||
guard let cursor = try execute(params)?.cursor else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return map(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
open func findFirst<T>(_ params: Any?..., map: (DBCursor)-> T?) throws -> T? {
|
||||
return try dispatcher.sync {
|
||||
guard let cursor = try execute(params)?.cursor else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return map(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
open func query(_ params:[String:Any?], forEach: (DBCursor)->Void) throws {
|
||||
try dispatcher.sync {
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
repeat {
|
||||
forEach(cursor);
|
||||
} while cursor.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func query(_ params:Any?..., forEach: (DBCursor)->Void) throws {
|
||||
try dispatcher.sync {
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
repeat {
|
||||
forEach(cursor);
|
||||
} while cursor.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func queryFirstMatching<T>(_ params:[String:Any?], forEachRowUntil: (DBCursor)->T?) throws -> T? {
|
||||
return try dispatcher.sync {
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
var result: T?;
|
||||
repeat {
|
||||
result = forEachRowUntil(cursor);
|
||||
} while result == nil && cursor.next();
|
||||
return result;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
open func queryFirstMatching<T>(_ params:Any?..., forEachRowUntil: (DBCursor)->T?) throws -> T? {
|
||||
var result: T? = nil;
|
||||
try dispatcher.sync {
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
repeat {
|
||||
result = forEachRowUntil(cursor);
|
||||
} while result == nil && cursor.next();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
open func query<T>(_ params:[String:Any?], map: (DBCursor)->T?) throws -> [T] {
|
||||
var result = [T]();
|
||||
try dispatcher.sync {
|
||||
var tmp: T? = nil;
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
repeat {
|
||||
tmp = map(cursor);
|
||||
if tmp != nil {
|
||||
result.append(tmp!);
|
||||
}
|
||||
} while cursor.next();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
open func query<T>(_ params:Any?..., map: (DBCursor)->T?) throws -> [T] {
|
||||
var result = [T]();
|
||||
try dispatcher.sync {
|
||||
var tmp: T? = nil;
|
||||
if let cursor = try execute(params)?.cursor {
|
||||
repeat {
|
||||
tmp = map(cursor);
|
||||
if tmp != nil {
|
||||
result.append(tmp!);
|
||||
}
|
||||
} while cursor.next();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
open func insert(_ params:Any?...) throws -> Int? {
|
||||
return try connection.dispatcher.sync {
|
||||
if params.count > 0 {
|
||||
_ = try self.bind(params);
|
||||
}
|
||||
self.reset(false);
|
||||
if try self.step(SQLITE_DONE) {
|
||||
return self.lastInsertRowId;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
open func insert(_ params:[String:Any?]) throws -> Int? {
|
||||
return try connection.dispatcher.sync {
|
||||
_ = try self.bind(params);
|
||||
self.reset(false);
|
||||
if try self.step(SQLITE_DONE) {
|
||||
return self.lastInsertRowId;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
open func update(_ params:Any?...) throws -> Int {
|
||||
return try connection.dispatcher.sync {
|
||||
_ = try self.execute(params);
|
||||
return self.changesCount;
|
||||
}
|
||||
}
|
||||
|
||||
open func update(_ params:[String:Any?]) throws -> Int {
|
||||
return try connection.dispatcher.sync {
|
||||
_ = try self.execute(params);
|
||||
return self.changesCount;
|
||||
}
|
||||
}
|
||||
|
||||
open func scalar(_ params:Any?...) throws -> Int? {
|
||||
return try dispatcher.sync {
|
||||
let cursor = try self.execute(params)?.cursor;
|
||||
return cursor?[0];
|
||||
}
|
||||
}
|
||||
|
||||
open func scalar(_ params:[String:Any?]) throws -> Int? {
|
||||
return try dispatcher.sync {
|
||||
let cursor = try self.execute(params)?.cursor;
|
||||
return cursor?[0];
|
||||
}
|
||||
}
|
||||
|
||||
open func scalar(_ params:Any?..., columnName: String) throws -> Int? {
|
||||
return try dispatcher.sync {
|
||||
let cursor = try self.execute(params)?.cursor;
|
||||
return cursor?[columnName];
|
||||
}
|
||||
}
|
||||
|
||||
open func scalar(_ params:[String:Any?], columnName: String) throws -> Int? {
|
||||
return try dispatcher.sync {
|
||||
let cursor = try self.execute(params)?.cursor;
|
||||
return cursor?[columnName];
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func reset(_ bindings:Bool=true) {
|
||||
sqlite3_reset(handle);
|
||||
if bindings {
|
||||
sqlite3_clear_bindings(handle);
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func check(_ result:Int32) throws -> Int32 {
|
||||
return try connection.check(result, statement: self);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class DBCursor {
|
||||
|
||||
fileprivate let connection: DBConnection;
|
||||
fileprivate let handle:OpaquePointer;
|
||||
|
||||
open lazy var columnCount:Int = Int(sqlite3_column_count(self.handle));
|
||||
|
||||
open lazy var columnNames:[String] = (0..<Int32(self.columnCount)).map { (idx:Int32) -> String in
|
||||
return String(cString: sqlite3_column_name(self.handle, idx)!);
|
||||
}
|
||||
|
||||
public init(statement:DBStatement) {
|
||||
self.connection = statement.connection;
|
||||
self.handle = statement.handle!;
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Double {
|
||||
return sqlite3_column_double(handle, Int32(index));
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Int {
|
||||
return Int(sqlite3_column_int64(handle, Int32(index)));
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Int32 {
|
||||
return sqlite3_column_int(handle, Int32(index));
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> String? {
|
||||
let ptr = sqlite3_column_text(handle, Int32(index));
|
||||
if ptr == nil {
|
||||
return nil;
|
||||
}
|
||||
return String(cString: UnsafePointer(ptr!));
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Bool {
|
||||
return sqlite3_column_int64(handle, Int32(index)) != 0;
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> [UInt8]? {
|
||||
let idx = Int32(index);
|
||||
let origPtr = sqlite3_column_blob(handle, idx);
|
||||
if origPtr == nil {
|
||||
return nil;
|
||||
}
|
||||
let count = Int(sqlite3_column_bytes(handle, idx));
|
||||
let ptr = origPtr?.assumingMemoryBound(to: UInt8.self)
|
||||
return DBCursor.convert(count, data: ptr!);
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Data? {
|
||||
let idx = Int32(index);
|
||||
let origPtr = sqlite3_column_blob(handle, idx);
|
||||
if origPtr == nil {
|
||||
return nil;
|
||||
}
|
||||
let count = Int(sqlite3_column_bytes(handle, idx));
|
||||
return Data(bytes: origPtr!, count: count);
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> Date {
|
||||
let timestamp = Double(sqlite3_column_int64(handle, Int32(index))) / 1000;
|
||||
return Date(timeIntervalSince1970: timestamp);
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> JID? {
|
||||
if let str:String = self[index] {
|
||||
return JID(str);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
open subscript(index: Int) -> BareJID? {
|
||||
if let str:String = self[index] {
|
||||
return BareJID(str);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Double? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Int? {
|
||||
// return forColumn(column) {
|
||||
// let v:Int? = self[$0];
|
||||
// print("for \(column), position \($0) got \(v)")
|
||||
// return v;
|
||||
// }
|
||||
if let idx = columnNames.firstIndex(of: column) {
|
||||
return self[idx];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Int32? {
|
||||
// return forColumn(column) {
|
||||
// let v:Int? = self[$0];
|
||||
// print("for \(column), position \($0) got \(v)")
|
||||
// return v;
|
||||
// }
|
||||
if let idx = columnNames.firstIndex(of: column) {
|
||||
return self[idx];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
open subscript(column: String) -> String? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Bool? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> [UInt8]? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Data? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> Date? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> JID? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
open subscript(column: String) -> BareJID? {
|
||||
return forColumn(column) {
|
||||
return self[$0];
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func forColumn<T>(_ column:String, exec:(Int)->T?) -> T? {
|
||||
if let idx = columnNames.firstIndex(of: column) {
|
||||
return exec(idx);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
fileprivate static func convert<T>(_ count: Int, data: UnsafePointer<T>) -> [T] {
|
||||
let buffer = UnsafeBufferPointer(start: data, count: count);
|
||||
return Array(buffer)
|
||||
}
|
||||
|
||||
open func next() -> Bool {
|
||||
return connection.dispatcher.sync {
|
||||
return sqlite3_step(self.handle) == SQLITE_ROW;
|
||||
}
|
||||
}
|
||||
|
||||
open func next() -> DBCursor? {
|
||||
return next() ? self : nil;
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
//
|
||||
// DBSchemaManager.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2017 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TigaseSwift
|
||||
|
||||
public class DBSchemaManager {
|
||||
|
||||
static let CURRENT_VERSION = 15;
|
||||
|
||||
fileprivate let dbConnection: DBConnection;
|
||||
|
||||
public init(dbConnection: DBConnection) {
|
||||
self.dbConnection = dbConnection;
|
||||
}
|
||||
|
||||
open func upgradeSchema() throws {
|
||||
var version = try! getSchemaVersion();
|
||||
while (version < DBSchemaManager.CURRENT_VERSION) {
|
||||
switch version {
|
||||
case 0:
|
||||
try loadSchemaFile(fileName: "/db-schema-1.sql");
|
||||
do {
|
||||
try dbConnection.execute("select preview from chat_history");
|
||||
} catch {
|
||||
try dbConnection.execute("ALTER TABLE chat_history ADD COLUMN preview TEXT");
|
||||
}
|
||||
try cleanUpDuplicatedChats();
|
||||
case 1:
|
||||
try loadSchemaFile(fileName: "/db-schema-2.sql");
|
||||
try cleanUpDuplicatedChats();
|
||||
default:
|
||||
try loadSchemaFile(fileName: "/db-schema-\(version + 1).sql");
|
||||
break;
|
||||
}
|
||||
version = try! getSchemaVersion();
|
||||
}
|
||||
|
||||
let journalMode = try dbConnection.prepareStatement("pragma journal_mode").findFirst(map: { cursor -> String? in
|
||||
return cursor["journal_mode"];
|
||||
})!;
|
||||
if journalMode != "wal" {
|
||||
try dbConnection.execute("PRAGMA journal_mode=WAL");
|
||||
}
|
||||
|
||||
// need to make sure that "error" column exists as there was an issue with db-schema-2.sql
|
||||
// which did not create this column
|
||||
do {
|
||||
try dbConnection.execute("select error from chat_history");
|
||||
} catch {
|
||||
try dbConnection.execute("ALTER TABLE chat_history ADD COLUMN error TEXT;");
|
||||
}
|
||||
|
||||
let toRemove: [(String,String,Int32)] = try dbConnection.prepareStatement("SELECT sess.account as account, sess.name as name, sess.device_id as deviceId FROM omemo_sessions sess WHERE NOT EXISTS (select 1 FROM omemo_identities i WHERE i.account = sess.account and i.name = sess.name and i.device_id = sess.device_id)").query([:] as [String: Any?], map: { (cursor:DBCursor) -> (String, String, Int32)? in
|
||||
return (cursor["account"]!, cursor["name"]!, cursor["deviceId"]!);
|
||||
});
|
||||
|
||||
try toRemove.forEach { tuple in
|
||||
let (account, name, device) = tuple;
|
||||
_ = try dbConnection.prepareStatement("DELETE FROM omemo_sessions WHERE account = :account AND name = :name AND device_id = :deviceId").update(["account": account, "name": name, "deviceId": device] as [String: Any?]);
|
||||
}
|
||||
}
|
||||
|
||||
open func getSchemaVersion() throws -> Int {
|
||||
return try self.dbConnection.prepareStatement("PRAGMA user_version").scalar() ?? 0;
|
||||
}
|
||||
|
||||
fileprivate func loadSchemaFile(fileName: String) throws {
|
||||
guard let bundle = Bundle.allFrameworks.first(where: { (bundle) -> Bool in
|
||||
guard let resourcePath = bundle.resourcePath else {
|
||||
return false;
|
||||
}
|
||||
return FileManager.default.fileExists(atPath: resourcePath.appending(fileName));
|
||||
}) else {
|
||||
return;
|
||||
}
|
||||
let resourcePath = bundle.resourcePath! + fileName;
|
||||
print("loading SQL from file", resourcePath);
|
||||
let dbSchema = try String(contentsOfFile: resourcePath, encoding: String.Encoding.utf8);
|
||||
print("read schema:", dbSchema);
|
||||
try dbConnection.execute(dbSchema);
|
||||
print("loaded schema from file", fileName);
|
||||
}
|
||||
|
||||
fileprivate func cleanUpDuplicatedChats() throws {
|
||||
// deal with duplicated chats for the same bare jid
|
||||
print("looking for duplicated chats...");
|
||||
let duplicates: [(String, String, Int)] = try dbConnection.prepareStatement("select min(c.id) as id, c.account, c.jid from (select count(id) as count, account, jid from chats group by account, jid) x inner join chats c on c.account = x.account and c.jid = x.jid where count > 1 group by c.account, c.jid").query() { (cursor) -> (String, String, Int) in
|
||||
let account: String = cursor["account"]!;
|
||||
let jid: String = cursor["jid"]!;
|
||||
let id: Int = cursor["id"] ?? 0;
|
||||
print("account", account, "jid", jid, "id", id);
|
||||
return (account, jid, id);
|
||||
}
|
||||
print("found duplicates", duplicates);
|
||||
try duplicates.forEach({ (account, jid, idToLeave) in
|
||||
let removed = try dbConnection.prepareStatement("delete from chats where account = ? and jid = ? and id <> :id").scalar(account, jid, idToLeave)!;
|
||||
print("for account", account, "and jid", jid, "removed", removed, "duplicated chats");
|
||||
});
|
||||
print("duplicated chats cleanup finished!");
|
||||
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// NotificationEncryptionKeys.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2019 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TigaseSwift
|
||||
|
||||
public class NotificationEncryptionKeys {
|
||||
|
||||
private static let storage = UserDefaults(suiteName: "group.snikket.notifications")!;
|
||||
|
||||
public static func key(for account: BareJID) -> Data? {
|
||||
storage.data(forKey: account.stringValue)
|
||||
}
|
||||
|
||||
public static func set(key: Data?, for account: BareJID) {
|
||||
storage.setValue(key, forKey: account.stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// AccountTableViewCell.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2017 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AccountTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet var accountLabel: UILabel!;
|
||||
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
//
|
||||
// AccountsTableViewController.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2017 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AccountsTableViewController: UITableViewController {
|
||||
|
||||
var accounts: [String] = [];
|
||||
|
||||
var delegate: ShareViewController?;
|
||||
|
||||
var selected: String? = nil;
|
||||
|
||||
override func viewDidLoad() {
|
||||
accounts = getAccounts();
|
||||
super.viewDidLoad();
|
||||
//tableView.register(AccountTableViewCell.self, forCellReuseIdentifier: "accountTableViewCell");
|
||||
}
|
||||
|
||||
func getAccounts() -> [String] {
|
||||
var accounts = [String]();
|
||||
let query = [ String(kSecClass) : kSecClassGenericPassword, String(kSecMatchLimit) : kSecMatchLimitAll, String(kSecReturnAttributes) : kCFBooleanTrue as Any, String(kSecAttrService) : "xmpp" ] as [String : Any];
|
||||
var result:AnyObject?;
|
||||
|
||||
let lastResultCode: OSStatus = withUnsafeMutablePointer(to: &result) {
|
||||
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0));
|
||||
}
|
||||
|
||||
if lastResultCode == noErr {
|
||||
if let results = result as? [[String:NSObject]] {
|
||||
for r in results {
|
||||
let name = r[String(kSecAttrAccount)] as! String;
|
||||
if let data = r[String(kSecAttrGeneric)] as? NSData {
|
||||
let dict = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? [String:AnyObject];
|
||||
if dict!["active"] as? Bool ?? false {
|
||||
accounts.append(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return accounts.count;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "accountTableViewCell", for: indexPath) as! AccountTableViewCell;
|
||||
let name = accounts[indexPath.row];
|
||||
cell.accountLabel.text = name;
|
||||
if selected != nil && selected! == name {
|
||||
cell.accessoryType = .checkmark;
|
||||
} else {
|
||||
cell.accessoryType = .none;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let account = accounts[indexPath.row];
|
||||
selected = account;
|
||||
delegate!.accountSelection(account: account);
|
||||
navigationController?.popViewController(animated: true);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
//
|
||||
// RecipientTableViewCell.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2017 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class RecipientTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet var name: UILabel!;
|
||||
@IBOutlet var jid: UILabel!;
|
||||
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
//
|
||||
// RecipientsSelectionViewController.swift
|
||||
//
|
||||
// Siskin IM
|
||||
// Copyright (C) 2017 "Tigase, Inc." <office@tigase.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. Look for COPYING file in the top folder.
|
||||
// If not, see https://www.gnu.org/licenses/.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import TigaseSwift
|
||||
|
||||
class RecipientsSelectionViewController: UITableViewController {
|
||||
|
||||
var selected: [JID] = [];
|
||||
|
||||
var allItems = [JID:RosterItem]();
|
||||
var items: [RosterItem] = [];
|
||||
|
||||
var xmppClient: XMPPClient! {
|
||||
didSet {
|
||||
let store = RosterModule.getRosterStore(xmppClient.sessionObject) as! DefaultRosterStore;
|
||||
self.allItems.removeAll();
|
||||
store.getJids().forEach({(jid) in
|
||||
if let item = store.get(for: jid) {
|
||||
allItems[jid] = item;
|
||||
}
|
||||
});
|
||||
updateItem(item: nil);
|
||||
}
|
||||
}
|
||||
|
||||
var delegate: ShareViewController?;
|
||||
|
||||
var sharedDefaults = UserDefaults(suiteName: "group.snikket.share");
|
||||
fileprivate let indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 80, height: 80));
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad();
|
||||
indicator.style = .gray;
|
||||
indicator.backgroundColor = UIColor.white;
|
||||
indicator.hidesWhenStopped = true;
|
||||
self.view.addSubview(indicator);
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
if xmppClient.state == .connecting {
|
||||
indicator.startAnimating();
|
||||
}
|
||||
super.viewWillAppear(animated);
|
||||
let view = self.parent!.view!;
|
||||
indicator.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2);
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return items.count;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "recipientTableViewCell", for: indexPath) as! RecipientTableViewCell;
|
||||
let item = items[indexPath.row];
|
||||
cell.name.text = item.name ?? item.jid.stringValue;
|
||||
if selected.contains(item.jid) {
|
||||
cell.accessoryType = .checkmark;
|
||||
} else {
|
||||
cell.accessoryType = .none;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let jid = items[indexPath.row].jid;
|
||||
if let idx = selected.firstIndex(of: jid) {
|
||||
selected.remove(at: idx);
|
||||
} else {
|
||||
selected.append(jid);
|
||||
}
|
||||
delegate?.recipientsChanged(selected);
|
||||
tableView.reloadData();
|
||||
}
|
||||
|
||||
func hideIndicator() {
|
||||
DispatchQueue.main.async {
|
||||
if self.indicator.isAnimating {
|
||||
self.indicator.stopAnimating();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateItem(item: RosterItem?) {
|
||||
if item != nil {
|
||||
allItems[item!.jid] = item!;
|
||||
}
|
||||
let showHidden = sharedDefaults!.bool(forKey: "RosterDisplayHiddenGroup");
|
||||
let tmp: [RosterItem] = allItems.values.filter({ (ri) -> Bool in
|
||||
return showHidden || !ri.groups.contains("Hidden");
|
||||
});
|
||||
items = tmp.sorted { (r1, r2) -> Bool in
|
||||
return (r1.name ?? r1.jid.stringValue).compare(r2.name ?? r2.jid.stringValue) == .orderedAscending;
|
||||
}
|
||||
tableView.reloadData();
|
||||
if item != nil {
|
||||
hideIndicator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "HSLuvSwift",
|
||||
"repositoryURL": "https://github.com/hsluv/hsluv-swift.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "9dee4378180f2a9a33c96bc20284cf64158dbe1b",
|
||||
"version": "2.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "libsignal",
|
||||
"repositoryURL": "https://github.com/tigase/libsignal",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "d23d5af0d729cf66b93cea607f3f84a34b9fddfd",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "TigaseSwift",
|
||||
"repositoryURL": "https://github.com/tigase/tigase-swift",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "d3953dcea80010ad433fa96d7ca6b989bf58850c",
|
||||
"version": "2.1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "TigaseSwiftOMEMO",
|
||||
"repositoryURL": "https://github.com/tigase/tigase-swift-omemo/",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "4c997df9a3a686b7e522ddffa4d2f2c070a94fa0",
|
||||
"version": "1.1.3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
5
Snikket/AppCore/Actions/AppActions.swift
Normal file
5
Snikket/AppCore/Actions/AppActions.swift
Normal file
|
@ -0,0 +1,5 @@
|
|||
enum AppAction: Codable {
|
||||
case flushState
|
||||
case changeFlow(_ flow: AppFlow)
|
||||
case tempAction(_ action: TempAction)
|
||||
}
|
3
Snikket/AppCore/Actions/TempActions.swift
Normal file
3
Snikket/AppCore/Actions/TempActions.swift
Normal file
|
@ -0,0 +1,3 @@
|
|||
enum TempAction: Codable {
|
||||
case dumb
|
||||
}
|
94
Snikket/AppCore/AppStore.swift
Normal file
94
Snikket/AppCore/AppStore.swift
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
In 99,99% of time YOU DON'T NEEDED TO CHANGE ANYTHING in this file!
|
||||
|
||||
This file declare global state object for whole app
|
||||
and reducers/actions/middleware types. Core of AppCore.
|
||||
*/
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
typealias Stateable = Codable & Equatable
|
||||
typealias AppStore = Store<AppState, AppAction>
|
||||
typealias Reducer<State: Stateable, Action: Codable> = (inout State, Action) -> Void
|
||||
typealias Middleware<State: Stateable, Action: Codable> = (State, Action) -> AnyPublisher<Action, Never>?
|
||||
|
||||
final class Store<State: Stateable, Action: Codable>: ObservableObject {
|
||||
// Fake variable for be able to trigger SwiftUI redraw after app state completely changed
|
||||
// this hack is needed because @Published wrapper sends signals on "willSet:"
|
||||
@Published private var dumbVar: UUID = UUID()
|
||||
|
||||
// State is read-only (changes only over reducers)
|
||||
private(set) var state: State {
|
||||
didSet {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.dumbVar = UUID()
|
||||
}
|
||||
} // signal to SwiftUI only when new state did set
|
||||
}
|
||||
|
||||
// Serial queue for performing any actions sequentially
|
||||
private let serialQueue = DispatchQueue(label: "im.narayana.snikket.core.serial.queue", qos: .userInteractive)
|
||||
|
||||
private let reducer: Reducer<State, Action>
|
||||
private let middlewares: [Middleware<State, Action>]
|
||||
private var middlewareCancellables: Set<AnyCancellable> = []
|
||||
|
||||
// Init
|
||||
init(
|
||||
initialState: State,
|
||||
reducer: @escaping Reducer<State, Action>,
|
||||
middlewares: [Middleware<State, Action>] = []) {
|
||||
state = initialState
|
||||
self.reducer = reducer
|
||||
self.middlewares = middlewares
|
||||
}
|
||||
|
||||
// Run reducers/middlewares
|
||||
func dispatch(_ action: Action) {
|
||||
serialQueue.sync { [weak self] in
|
||||
guard let wSelf = self else { return }
|
||||
let newState = wSelf.dispatch(wSelf.state, action)
|
||||
wSelf.state = newState
|
||||
}
|
||||
}
|
||||
|
||||
private func dispatch(_ currentState: State, _ action: Action) -> State {
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
// Do reducing
|
||||
var newState = currentState
|
||||
reducer(&newState, action)
|
||||
|
||||
// Dispatch all middleware functions
|
||||
for middleware in middlewares {
|
||||
guard let middleware = middleware(newState, action) else {
|
||||
break
|
||||
}
|
||||
middleware
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveValue: dispatch)
|
||||
.store(in: &middlewareCancellables)
|
||||
}
|
||||
|
||||
// Check performance
|
||||
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
|
||||
if timeElapsed > 0.05 {
|
||||
#if DEBUG
|
||||
print(
|
||||
"""
|
||||
--
|
||||
(Ignore this warning ONLY in case, when execution is paused by your breakpoint)
|
||||
🕐Execution time: \(timeElapsed)
|
||||
❌WARNING! Some reducers/middlewares work too long! It will lead to issues in production build!
|
||||
Because of execution each action is synchronous the any stuck will reduce performance dramatically.
|
||||
Probably you need check which part of reducer/middleware should be async (wrapped with Futures, as example)
|
||||
--
|
||||
"""
|
||||
)
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
return newState
|
||||
}
|
||||
}
|
36
Snikket/AppCore/Middleware/LoggerMiddleware.swift
Normal file
36
Snikket/AppCore/Middleware/LoggerMiddleware.swift
Normal file
|
@ -0,0 +1,36 @@
|
|||
import Foundation
|
||||
import Combine
|
||||
|
||||
let isConsoleLoggingEnabled = false
|
||||
|
||||
#if DEBUG
|
||||
func loggerMiddleware() -> Middleware<AppState, AppAction> {
|
||||
{ state, action in
|
||||
let timeStr = dateFormatter.string(from: Date())
|
||||
var actionStr = "\(action)"
|
||||
actionStr = String(actionStr.prefix(200)) + " ..."
|
||||
var stateStr = "\(state)"
|
||||
stateStr = String(stateStr.prefix(200)) + " ..."
|
||||
|
||||
let str = "\(timeStr) ➡️ \(actionStr)\n\(timeStr) ✅ \(stateStr)\n"
|
||||
print(str)
|
||||
if isConsoleLoggingEnabled {
|
||||
NSLog(str)
|
||||
}
|
||||
return Empty().eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
#else
|
||||
func loggerMiddleware() -> Middleware<AppState, AppAction> {
|
||||
{ _, _ in
|
||||
Empty().eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private var dateFormatter: DateFormatter {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
|
||||
formatter.dateFormat = "MM-dd HH:mm:ss.SSS"
|
||||
return formatter
|
||||
}
|
16
Snikket/AppCore/Middleware/TempMiddleware.swift
Normal file
16
Snikket/AppCore/Middleware/TempMiddleware.swift
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Combine
|
||||
|
||||
final class TempMiddleware {
|
||||
static let shared = TempMiddleware()
|
||||
|
||||
func middleware(state: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
||||
switch action {
|
||||
case .tempAction(.dumb):
|
||||
return Just(AppAction.flushState)
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
default:
|
||||
return Empty().eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
}
|
3
Snikket/AppCore/Models/TempModel.swift
Normal file
3
Snikket/AppCore/Models/TempModel.swift
Normal file
|
@ -0,0 +1,3 @@
|
|||
struct TempModel: Stateable {
|
||||
var some: Bool
|
||||
}
|
16
Snikket/AppCore/Reducers/AppReducer.swift
Normal file
16
Snikket/AppCore/Reducers/AppReducer.swift
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Foundation
|
||||
|
||||
extension AppState {
|
||||
static func reducer(state: inout AppState, action: AppAction) {
|
||||
switch action {
|
||||
case .flushState:
|
||||
state = AppState()
|
||||
|
||||
case .changeFlow(let flow):
|
||||
state.currentFlow = flow
|
||||
|
||||
case .tempAction(let action):
|
||||
TempState.reducer(state: &state.tempState, action: action)
|
||||
}
|
||||
}
|
||||
}
|
9
Snikket/AppCore/Reducers/TempReducer.swift
Normal file
9
Snikket/AppCore/Reducers/TempReducer.swift
Normal file
|
@ -0,0 +1,9 @@
|
|||
extension TempState {
|
||||
static func reducer(state: inout TempState, action: TempAction) {
|
||||
switch action {
|
||||
case .dumb:
|
||||
state = .init()
|
||||
state.someModel = .init(some: true)
|
||||
}
|
||||
}
|
||||
}
|
22
Snikket/AppCore/State/AppState.swift
Normal file
22
Snikket/AppCore/State/AppState.swift
Normal file
|
@ -0,0 +1,22 @@
|
|||
import Foundation
|
||||
|
||||
enum AppFlow: Codable {
|
||||
case start
|
||||
}
|
||||
|
||||
struct AppState: Stateable {
|
||||
var appVersion: String
|
||||
var currentFlow: AppFlow
|
||||
|
||||
var tempState: TempState
|
||||
}
|
||||
|
||||
// MARK: Init
|
||||
extension AppState {
|
||||
init() {
|
||||
appVersion = Const.appVersion
|
||||
currentFlow = .start
|
||||
|
||||
tempState = .init()
|
||||
}
|
||||
}
|
18
Snikket/AppCore/State/TempState.swift
Normal file
18
Snikket/AppCore/State/TempState.swift
Normal file
|
@ -0,0 +1,18 @@
|
|||
import Foundation
|
||||
|
||||
enum TempNavigationState: Stateable {
|
||||
case main
|
||||
case details
|
||||
}
|
||||
|
||||
struct TempState: Stateable {
|
||||
var navigation: TempNavigationState
|
||||
var someModel: TempModel?
|
||||
}
|
||||
|
||||
// MARK: Init
|
||||
extension TempState {
|
||||
init() {
|
||||
navigation = .main
|
||||
}
|
||||
}
|
2
Snikket/Generated/.gitignore
vendored
Normal file
2
Snikket/Generated/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
9
Snikket/Helpers/AppStateJSON.swift
Normal file
9
Snikket/Helpers/AppStateJSON.swift
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Foundation
|
||||
|
||||
extension AppState {
|
||||
func json() -> String {
|
||||
let encoder = JSONEncoder()
|
||||
guard let data = try? encoder.encode(self) else { return "AppState encoding error" }
|
||||
return String(data: data, encoding: .utf8) ?? "AppState encoding error"
|
||||
}
|
||||
}
|
7
Snikket/Helpers/Bool+Extensions.swift
Normal file
7
Snikket/Helpers/Bool+Extensions.swift
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Foundation
|
||||
|
||||
extension Bool {
|
||||
var intValue: Int {
|
||||
self ? 1 : 0
|
||||
}
|
||||
}
|
24
Snikket/Helpers/Const.swift
Normal file
24
Snikket/Helpers/Const.swift
Normal file
|
@ -0,0 +1,24 @@
|
|||
import Foundation
|
||||
|
||||
struct Const {
|
||||
// Network
|
||||
#if DEBUG
|
||||
static let baseUrl = "staging.some.com/api"
|
||||
#else
|
||||
static let baseUrl = "prod.some.com/api"
|
||||
#endif
|
||||
static let requestTimeout = 15.0
|
||||
static let networkLogging = true
|
||||
|
||||
// App
|
||||
static var appVersion: String {
|
||||
let info = Bundle.main.infoDictionary
|
||||
let appVersion = info?["CFBundleShortVersionString"] as? String ?? "Unknown"
|
||||
let appBuild = info?[kCFBundleVersionKey as String] as? String ?? "Unknown"
|
||||
return "v \(appVersion)(\(appBuild))"
|
||||
}
|
||||
|
||||
static var appName: String {
|
||||
Bundle.main.bundleIdentifier ?? "Snikket iOS"
|
||||
}
|
||||
}
|
23
Snikket/Helpers/UserDefaultsWrapper.swift
Normal file
23
Snikket/Helpers/UserDefaultsWrapper.swift
Normal file
|
@ -0,0 +1,23 @@
|
|||
import Foundation
|
||||
|
||||
@propertyWrapper
|
||||
struct Storage<T> {
|
||||
private let key: String
|
||||
private let defaultValue: T
|
||||
|
||||
init(key: String, defaultValue: T) {
|
||||
self.key = key
|
||||
self.defaultValue = defaultValue
|
||||
}
|
||||
|
||||
var wrappedValue: T {
|
||||
get {
|
||||
// Read value from UserDefaults
|
||||
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
|
||||
}
|
||||
set {
|
||||
// Set value to UserDefaults
|
||||
UserDefaults.standard.set(newValue, forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"provides-namespace" : true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.180",
|
||||
"green" : "0.180",
|
||||
"red" : "0.180"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.471",
|
||||
"green" : "0.471",
|
||||
"red" : "0.471"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.902",
|
||||
"green" : "0.902",
|
||||
"red" : "0.902"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.973",
|
||||
"green" : "0.973",
|
||||
"red" : "0.973"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.741",
|
||||
"green" : "0.741",
|
||||
"red" : "0.741"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "1.000",
|
||||
"green" : "1.000",
|
||||
"red" : "1.000"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"provides-namespace" : true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.976",
|
||||
"green" : "0.792",
|
||||
"red" : "0.565"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.965",
|
||||
"green" : "0.710",
|
||||
"red" : "0.392"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.953",
|
||||
"green" : "0.588",
|
||||
"red" : "0.129"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.824",
|
||||
"green" : "0.463",
|
||||
"red" : "0.098"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.855",
|
||||
"green" : "0.659",
|
||||
"red" : "0.624"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.796",
|
||||
"green" : "0.525",
|
||||
"red" : "0.475"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.710",
|
||||
"green" : "0.318",
|
||||
"red" : "0.247"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.624",
|
||||
"green" : "0.247",
|
||||
"red" : "0.188"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.980",
|
||||
"green" : "0.831",
|
||||
"red" : "0.506"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.969",
|
||||
"green" : "0.765",
|
||||
"red" : "0.310"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.957",
|
||||
"green" : "0.663",
|
||||
"red" : "0.012"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.820",
|
||||
"green" : "0.533",
|
||||
"red" : "0.008"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.643",
|
||||
"green" : "0.667",
|
||||
"red" : "0.737"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.498",
|
||||
"green" : "0.533",
|
||||
"red" : "0.631"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.282",
|
||||
"green" : "0.333",
|
||||
"red" : "0.475"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.216",
|
||||
"green" : "0.251",
|
||||
"red" : "0.365"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.655",
|
||||
"green" : "0.839",
|
||||
"red" : "0.647"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue