swiftスクリプトプログラミング:ワンタッチでAppIconを生成する

13781 ワード

Xcode 8以降はプラグインがサポートされておらず、XcodeキーでAppIconを生成することができず、良い解決策が見つからず、怒って自分でAppIconを生成するためのスクリプトを書くことにしました.以下は本文です.弟はレンガを投げて玉を引いて、書くのが悪いところがあります.
ソースアドレス
事前準備
swiftバージョンの表示
まず、Macのswiftバージョンを確認します.
swift --version

私のコンピュータの実行結果はこうです.
Apple Swift version 4.0 (swiftlang-900.0.65 clang-900.0.37)
Target: x86_64-apple-macosx10.9

それからXcodeでswiftファイルを作ってswiftスクリプトを書くことができますが、単独でswiftファイルを建てて、Xcodeの編集はとても友好的ではありません.私の案はMacで運行しているCommand Line Toolプロジェクトを建てることです.そうすれば、コードのヒントがあります.そうしないと、書くのが苦痛です.もし大物たちがもっと良い方法があれば、弟を指導することができます.
swiftスクリプトプログラミングの小さな知識
ターミナル入出力
スクリプトを入手したばかりで、私たちは最初に端末でどのように入力と出力を行うかを事前に理解しなければなりません.次は入力と出力の方法です.
しゅつりょく
入力は簡単で、皆さんもよく知っています.printです.次はコードの例です.
print("Hello world!")

次のようにしてみてください(test.swiftはあなたのファイル名です):
swift test.swift

実行すると端末に1行の字が表示されます:Hello world!
これで私たちの最初のswiftスクリプトが完成しました.
入力
どのように出力するかを知るには、どのように入力するかを知る必要があります.入力も非常に簡単です.次はコードの例です.
print("     :")
if let input = readLine() {
    print("      :\(input)")
}

実行後に表示される結果:
     :
Hello world!
      :Hello world!

これで入力も完了し、swiftスクリプトプログラミングも入門しました.
swiftスクリプトで他のコマンドを呼び出す
私たちがよく使うコマンドはたくさんあります.例えば、echo、mkdir、cdなどです.swiftで直接呼び出すことができますか.答えはいいです.簡単な例で理解してみましょう.深く研究したいなら、転送ドアを研究してみましょう.
import Foundation

func execute(path: String, arguments: [String]? = nil) -> Int {
    let process = Process()
    process.launchPath = path
    if arguments != nil {
        process.arguments = arguments!
    }
    process.launch()
    process.waitUntilExit()
    return Int(process.terminationStatus)

}

let status = execute(path: "/bin/ls")
print("Status = \(status)")

以上のスクリプトは、端末でlsコマンドを実行したものに相当します.コマンドの経路が分からない場合は、whereで検索してみてください.例えば、
where ls

これは、実行後の結果です.
ls: aliased to ls -G
/bin/ls

ここの/bin/lsはlsコマンドのパスです.
スクリプトの作成を開始
読み込みinput.png
まず、変換が必要な画像から読み出します.次は主なコードです.
import Foundation

let inputPath = "input.png"
let inoutData = try Data(contentsOf: url)
print("    :\(inoutData.count / 1024) kb")
let dataProvider = CGDataProvider(data: inoutData as CFData)
if let inputImage = CGImage(pngDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent) {
    /// inputImage         
}else {
    print("    ,     png  ")
}

AppIconを生成します.appiconsetとContents.json
ここでファイルの操作を設計して、FileManagerを使って、みんなはすでに軽自動車が熟知していることを信じて、私はいくつかの主要なコードを貼って、みんなは全体の版を見て私のgithubソースコードに行って見ればいいです:
import Foundation

/// AppIcon model
struct AppIconImageItem: Codable {
    let size: String
    let idiom: String
    let filename: String
    let scale: String
    let role: String?
    let subtype: String?
}

struct AppIconInfo: Codable {
    let version: Int
    let author: String
}

struct AppIcon: Codable {
    var images: [AppIconImageItem]
    let info: AppIconInfo
}


///   contentsJson
///
/// - Parameter appIcon:    appIcon
func createAppIconContentsJson(appIcon: AppIcon) {
    print("
contentsJson
"
) let encoder = JSONEncoder() do { encoder.outputFormatting = .prettyPrinted let appIconData = try encoder.encode(appIcon) if let appIconStr = String.init(data: appIconData, encoding: .utf8) { let contentJsonPath = "AppIcon.appiconset/Contents.json" let contentJsonUrl = URL(fileURLWithPath: contentJsonPath) try appIconStr.write(to: contentJsonUrl, atomically: true, encoding: .utf8) print("contentsJson
"
) }else { print("contentsJson ") } }catch { print(error.localizedDescription) } } /// appicon /// /// - Parameter appIcon: appicon func createFile(appIcon: AppIcon, image: CGImage) { let fileManager = FileManager.default let filePath = "AppIcon.appiconset" do { if fileManager.fileExists(atPath: filePath) { try fileManager.removeItem(atPath: filePath) } try fileManager.createDirectory(atPath: filePath, withIntermediateDirectories: true, attributes: nil) createAppIconContentsJson(appIcon: appIcon) print("~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~") }catch { print(" \(filePath) ") print(error.localizedDescription) } }

異なるサイズのイメージを生成
画像を生成するにはFoundationフレームワークのCore Graphicsフレームワークを使用します.次は主なコードです.
import Foundation


///     image
///
/// - Parameters:
///   - size:    size
///   - scale:   ,  @2x  2 
///   - filename:    
func createImage(size: CGSize, scale: CGFloat, image: CGImage, filename: String) {
    print("      : \(filename)")
    let width  = Int(size.width * scale)
    let height = Int(size.height * scale)
    let bitsPerComponent = image.bitsPerComponent
    let bytesPerRow = image.bytesPerRow
    let colorSpace  = image.colorSpace

    if let context = CGContext.init(data: nil,
                                    width: width,
                                    height: height,
                                    bitsPerComponent: bitsPerComponent,
                                    bytesPerRow: bytesPerRow,
                                    space: colorSpace!,
                                    bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {
        context.interpolationQuality = .high
        context.draw(image, in: .init(origin: .zero, size: .init(width: width, height: height)))
        if let inputImage = context.makeImage() {
            let outputImagePath = "AppIcon.appiconset/\(filename)"
            let outputUrl = URL(fileURLWithPath: outputImagePath) as CFURL
            let destination = CGImageDestinationCreateWithURL(outputUrl, kUTTypePNG, 1, nil)
            if let destination = destination {
                CGImageDestinationAddImage(destination, inputImage, nil)
                if CGImageDestinationFinalize(destination) {
                    print("  : \(filename)     
"
) }else { print(" : \(filename)
"
) } } }else { print(" : \(filename)
"
) } } }

最後に、以下の完成したスクリーンショットを貼ります.
上はただ一部の主要なコードで、完全なコードは多すぎて、みんなは私のgithubアドレスに行ってダウンロードして以下を実行することができて、もし何か悪いところがあれば、みんなを歓迎して教えます~~