Swiftpack.co - nearfri/XCResource as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by nearfri.
nearfri/XCResource 0.9.25
A command line tool for generating Swift code for xcassets and generating localizable strings from Swift code
⭐️ 6
πŸ•“ 7 weeks ago
macOS
.package(url: "https://github.com/nearfri/XCResource.git", from: "0.9.25")

XCResource

Swift codecov

XCResourceλŠ” xcassets λ¦¬μ†ŒμŠ€ λ‘œλ”©κ³Ό λ‹€κ΅­μ–΄ 지원을 λ„μ™€μ£ΌλŠ” μ»€λ§¨λ“œλΌμΈ νˆ΄μž…λ‹ˆλ‹€.

이λ₯Ό μ΄μš©ν•΄ 이미지, 컬러, λ‹€κ΅­μ–΄ λ¬Έμžμ—΄μ„ μ‰½κ²Œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:

let image = UIImage.named(.settings)
let color = UIColor.named(.coralPink)
let string = String.localized(.done)
let text = String.formatted(.alert_deleteFile(fileName: fileName))

제곡기λŠ₯

xcresourceλŠ” λ‹€μŒμ˜ ν•˜μœ„ μ»€λ§¨λ“œλ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€:

  • xcassets2swift: xcassets을 μœ„ν•œ Swift μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • fonts2swift: fontλ₯Ό μœ„ν•œ Swift μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • strings2swift: strings 파일둜 Swift enum을 μƒμ„±ν•©λ‹ˆλ‹€.
  • swift2strings: Swift enum으둜 strings νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€.
  • key2form: Swift enum으둜 format string μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • strings2csv: strings 파일둜 CSV νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€.
  • csv2strings: CSV 파일둜 strings νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€.
  • init: Manifest νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€.
  • run (default): Manifest νŒŒμΌμ— λ‚˜μ—΄λœ ν•˜μœ„ μ»€λ§¨λ“œλ“€μ„ μ‹€ν–‰ν•©λ‹ˆλ‹€.

μ„€μΉ˜

Mint

mint install nearfri/XCResource

Make

git clone https://github.com/nearfri/XCResource.git
cd XCResource
make build install

μ‚¬μš© 예제

xcassets 이미지 λ‘œλ”©ν•˜κΈ°

https://user-images.githubusercontent.com/323940/202911680-3bb7bed7-ccaf-40c2-b136-439ff05b983b.mov

xcresource xcassets2swiftλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

xcrun --sdk macosx mint run xcresource xcassets2swift \
    --xcassets-path ../SampleApp/Assets.xcassets \
    --asset-type imageset \
    --swift-path ../SampleApp/ResourceKeys/ImageKey.swift \
    --key-type-name ImageKey

μ•„λž˜μ™€ 같은 μ½”λ“œκ°€ μƒμ„±λ©λ‹ˆλ‹€:

struct ImageKey: ExpressibleByStringLiteral, Hashable {
    var rawValue: String
    
    init(_ rawValue: String) {
        self.rawValue = rawValue
    }
    
    init(stringLiteral value: String) {
        self.rawValue = value
    }
}

// MARK: - Assets.xcassets

extension ImageKey {
    // MARK: Places
    static let places_authArrow: ImageKey = "Places/authArrow"
    static let places_authClose: ImageKey = "Places/authClose"
    
    // MARK: Settings
    static let settings: ImageKey = "settings"
    static let settingsAppearance: ImageKey = "settingsAppearance"
    ...

UIImage에 μƒμ„±μžλ₯Ό μΆ”κ°€ν•΄μ€λ‹ˆλ‹€:

extension UIImage {
    static func named(_ key: ImageKey) -> UIImage {
        return UIImage(named: key.rawValue, in: .module, compatibleWith: nil)!
    }
}

이제 μžλ™μ™„μ„±κ³Ό ν•¨κ»˜ 이미지λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:

imageView.image = .named(.settings)

μ»€μŠ€ν…€ 폰트 λ‘œλ”©ν•˜κΈ°

https://user-images.githubusercontent.com/323940/209695591-92fd68f8-141e-4766-ab6d-bcfdd072ac74.mov

xcresource fonts2swiftλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

xcrun --sdk macosx mint run xcresource fonts2swift \
    --fonts-path ../SampleApp/Fonts \
    --swift-path ../SampleApp/ResourceKeys/FontKey.swift \
    --key-type-name FontKey

μ•„λž˜μ™€ 같은 μ½”λ“œκ°€ μƒμ„±λ©λ‹ˆλ‹€:

public struct FontKey: Hashable {
    public var fontName: String
    public var familyName: String
    public var style: String
    public var path: String
    
    public init(fontName: String, familyName: String, style: String, path: String) {
        self.fontName = fontName
        self.familyName = familyName
        self.style = style
        self.path = path
    }
}

public extension FontKey {
    static let allKeys: [FontKey] = [
        // Open Sans
        .openSans_bold,
        .openSans_regular,
    ]
}

public extension FontKey {
    // MARK: Open Sans
    
    static let openSans_bold: FontKey = .init(
        fontName: "OpenSans-Bold",
        familyName: "Open Sans",
        style: "Bold",
        path: "OpenSans/OpenSans-Bold.ttf")
    
    ...

UIFont에 μƒμ„±μžλ₯Ό μΆ”κ°€ν•΄μ€λ‹ˆλ‹€:

extension UIFont {
    static func named(_ key: FontKey, size: CGFloat) -> UIFont {
        return UIFont(name: key.fontName, size: size)!
    }
}

이제 μžλ™μ™„μ„±κ³Ό ν•¨κ»˜ 폰트λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:

label.font = .named(.openSans_bold)

strings 파일둜 Swift enum λ§Œλ“€κΈ°

https://user-images.githubusercontent.com/323940/202911792-bc48ef57-0ff3-404b-84b4-94931350e847.mov

enum νƒ€μž…μ˜ 빈 StringKeyλ₯Ό λ§Œλ“€μ–΄μ€λ‹ˆλ‹€:

enum StringKey: String, CaseIterable {

}

String에 μƒμ„±μžλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€:

extension String {
    static func localized(_ key: StringKey) -> String {
        return NSLocalizedString(key.rawValue, bundle: .module, comment: "")
    }
}

strings νŒŒμΌμ„ μ€€λΉ„ν•©λ‹ˆλ‹€:

"cancel" = "μ·¨μ†Œ";
"confirm" = "확인";

xcresource strings2swiftλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

xcrun --sdk macosx mint run xcresource strings2swift \
    --resources-path ../SampleApp \
    --language ko \
    --swift-path ../SampleApp/ResourceKeys/StringKey.swift \

μ•„λž˜μ™€ 같이 StringKeyκ°€ μ—…λ°μ΄νŠΈ λ©λ‹ˆλ‹€:

enum StringKey: String, CaseIterable {
    /// μ·¨μ†Œ
    case cancel
    
    /// 확인
    case confirm
}

이제 μžλ™μ™„μ„±κ³Ό ν•¨κ»˜ μ§€μ—­ν™”λœ λ¬Έμžμ—΄μ„ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:

label.text = .localized(.cancel)

Swift enum으둜 strings 파일 λ§Œλ“€κΈ°

https://user-images.githubusercontent.com/323940/202911866-cbd49782-05c8-4908-8e34-5187ad867331.mov

swift2stringsλŠ” strings2swiftμ™€λŠ” λ°˜λŒ€λ‘œ enum을 strings둜 λ³€ν™˜ν•΄μ€λ‹ˆλ‹€.

xcrun --sdk macosx mint run xcresource swift2strings \
    --swift-path ../SampleApp/ResourceKeys/StringKey.swift \
    --resources-path ../SampleApp \
    --language-config ko:comment

μ•„λž˜μ™€ 같이 strings 파일이 μ—…λ°μ΄νŠΈ λ©λ‹ˆλ‹€:

/* μ·¨μ†Œ */
"cancel" = "μ·¨μ†Œ";

/* 확인 */
"confirm" = "확인";

Swift enum으둜 format string μ½”λ“œ λ§Œλ“€κΈ°

https://user-images.githubusercontent.com/323940/202911913-b9603b3b-cac7-40c2-8573-75e7617edd9c.mov

StringKey의 case에 format string ν˜•μ‹μ˜ 주석을 μΆ”κ°€ν•©λ‹ˆλ‹€:

enum StringKey: String, CaseIterable {
    /// "%{fileName}" νŒŒμΌμ€ μ‚­μ œλ©λ‹ˆλ‹€.\n이 λ™μž‘μ€ μ·¨μ†Œν•  수 μ—†μŠ΅λ‹ˆλ‹€.
    case alert_deleteFile
}

xcresource key2form을 μ‹€ν–‰ν•©λ‹ˆλ‹€:

xcrun --sdk macosx mint run xcresource key2form \
    --key-file-path ../SampleApp/ResourceKeys/StringKey.swift \
    --form-file-path ../SampleApp/ResourceKeys/StringForm.swift \
    --form-type-name StringForm \
    --issue-reporter xcode

μ•„λž˜μ™€ 같은 μ½”λ“œκ°€ μƒμ„±λ©λ‹ˆλ‹€:

struct StringForm {
    var key: String
    var arguments: [CVarArg]
}

extension StringForm {
    /// "%{fileName}" νŒŒμΌμ€ μ‚­μ œλ©λ‹ˆλ‹€.\n이 λ™μž‘μ€ μ·¨μ†Œν•  수 μ—†μŠ΅λ‹ˆλ‹€.
    static func alert_deleteFile(fileName: String) -> StringForm {
        return StringForm(key: StringKey.alert_deleteFile.rawValue, arguments: [fileName])
    }
}

String에 μƒμ„±μžλ₯Ό μΆ”κ°€ν•΄μ€λ‹ˆλ‹€:

extension String {
    static func formatted(_ form: StringForm) -> String {
        let format = NSLocalizedString(form.key, bundle: .module, comment: "")
        return String(format: format, locale: .current, arguments: form.arguments)
    }
}

이제 μžλ™μ™„μ„±κ³Ό ν•¨κ»˜ μ§€μ—­ν™”λœ λ¬Έμžμ—΄μ„ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:

label.text = .formatted(.alert_deleteFile(fileName: fileName))

strings 파일둜 CSV 파일 λ§Œλ“€κΈ°

https://user-images.githubusercontent.com/323940/202911933-e1041967-9fd1-4eb5-9c73-999cdbbb6a13.mov

xcresource strings2csvλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

mint run xcresource strings2csv \
    --resources-path ../SampleApp \
    --development-language ko \
    --csv-path ./localizations.csv \
    --header-style long-ko \
    --write-bom

μ•„λž˜μ™€ 같은 csv 파일이 λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€:

Key Comment ν•œκ΅­μ–΄ (ko) μ˜μ–΄ (en)
cancel μ·¨μ†Œ μ·¨μ†Œ
confirm 확인 확인

CSV 파일둜 strings 파일 λ§Œλ“€κΈ°

https://user-images.githubusercontent.com/323940/202911964-00ebcb96-90d8-430d-8385-e0cecbe8b181.mov

xcresource csv2stringsλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

mint run xcresource csv2strings \
    --csv-path ./localizations.csv \
    --header-style long-ko \
    --resources-path ../SampleApp

μ•„λž˜μ™€ 같이 strings 파일이 λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€:

/* μ·¨μ†Œ */
"cancel" = "μ·¨μ†Œ";

/* 확인 */
"confirm" = "확인";

XCResourceSample.xcworkspaceμ—μ„œ 적용 예제λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

λΌμ΄μ„ μŠ€

XCResourceλŠ” MIT λΌμ΄μ„ μŠ€μ— 따라 λ°°ν¬λ©λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ LICENSEλ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

GitHub

link
Stars: 6
Last commit: 7 weeks ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Related Packages

Release Notes

0.9.25
7 weeks ago

What's Changed

Full Changelog: https://github.com/nearfri/XCResource/compare/0.9.24...0.9.25

Asset Checksums

  • xcresource.zip: 8294ff8872584a3c41ef991fb24193004774013a9b41a421433f6c28ee5fc92a
  • xcresource.artifactbundle.zip: b4a297dea6b6c8df93dc7149d7d548e38ec699cdcfd2477b33c013da52fd7249

Swift Package Manager snippet

.binaryTarget(
    name: "xcresource",
    url: "https://github.com/nearfri/XCResource/releases/download/0.9.25/xcresource.artifactbundle.zip",
    checksum: "b4a297dea6b6c8df93dc7149d7d548e38ec699cdcfd2477b33c013da52fd7249"
)

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics