@@ -24,79 +24,65 @@ public class AssetGenerator {
2424 let filename : String
2525 }
2626
27- private static let platformIdiomMap : [ AssetKit . Platform : Set < String > ] = [
28- . iphone: Set ( [ " iphone " , " ios-marketing " ] ) ,
29- . ipad: Set ( [ " ipad " , " ios-marketing " ] ) ,
30- . ios: Set ( [ " iphone " , " ipad " , " ios-marketing " ] ) ,
31- . watch: Set ( [ " watch " , " watch-marketing " ] ) ,
32- . car: Set ( [ " car " , " car " ] ) ,
33- . mac: Set ( [ " mac " ] ) ,
34- ]
35-
3627 public func generateIconSet( input: NSImage ,
3728 outputPath: String ,
38- platforms: [ AssetKit . Platform ] = [ . ios] ) throws {
39- guard let imageSource = AssetUtils . createCGImageSource ( from: input) else {
40- throw AssetGeneratorError . dataSourceError
41- }
42-
43- try generateIconSet ( imageSource: imageSource, outputPath: outputPath, platforms: platforms)
29+ platforms: Set < AssetKit . Platform > = [ . ios] ,
30+ prefersUniversal: Bool = true ) throws {
31+ let imageSource = try AssetUtils . createCGImageSource ( from: input)
32+ try generateIconSet (
33+ imageSource: imageSource,
34+ outputPath: outputPath,
35+ platforms: platforms,
36+ prefersUniversal: prefersUniversal)
4437 }
4538
4639 public func generateIconSet( inputPath: String ,
4740 outputPath: String ,
48- platforms: [ AssetKit . Platform ] = [ . ios] ) throws {
49- guard let imageSource = AssetUtils . createCGImageSource ( from: inputPath) else {
50- throw AssetGeneratorError . dataSourceError
51- }
52-
53- try generateIconSet ( imageSource: imageSource, outputPath: outputPath, platforms: platforms)
41+ platforms: Set < AssetKit . Platform > = [ . ios] ,
42+ prefersUniversal: Bool = true ) throws {
43+ let imageSource = try AssetUtils . createCGImageSource ( from: inputPath)
44+ try generateIconSet (
45+ imageSource: imageSource,
46+ outputPath: outputPath,
47+ platforms: platforms,
48+ prefersUniversal: prefersUniversal)
5449 }
5550
5651 private func generateIconSet( imageSource: CGImageSource ,
5752 outputPath: String ,
58- platforms: [ AssetKit . Platform ] = [ . ios] ) throws {
59- guard var config = AssetUtils . loadResourceJson ( filename: " icon_contents " ) else {
60- throw AssetGeneratorError . resourceError
61- }
53+ platforms: Set < AssetKit . Platform > = [ . ios] ,
54+ prefersUniversal: Bool ) throws {
55+ var config = try AssetUtils . loadResourceJson ( filename: " icon_contents " )
6256
63- let outputFolder = URL ( fileURLWithPath: outputPath) . appendingPathComponent ( " AppIcon.appiconset " )
57+ let iconSetFileName = " AppIcon.appiconset "
58+ let outputFolder = URL ( fileURLWithPath: outputPath) . appendingPathComponent ( iconSetFileName)
6459 try AssetUtils . createDirectoryIfNeeded ( url: outputFolder)
6560
6661 var resizeConfigs : [ ResizeConfiguration ] = [ ]
6762 var filteredImageConfigs : [ [ String : Any ] ] = [ ]
6863 guard let imageConfigs = config [ " images " ] as? [ [ String : Any ] ] else {
6964 throw AssetGeneratorError . configError
7065 }
71- for imageConfig in imageConfigs {
72- guard let idiom = imageConfig [ " idiom " ] as? String else {
73- throw AssetGeneratorError . configError
74- }
7566
76- func shouldUseThisConfig( ) -> Bool {
77- for platform in platforms {
78- guard let platformIdiomStringSet = Self . platformIdiomMap [ platform] else {
79- continue
80- }
81- if platformIdiomStringSet. contains ( idiom) {
82- return true
83- }
84- }
85- return false
67+ for imageConfig in imageConfigs {
68+ guard let configPlatform = getPlatform ( from: imageConfig) ,
69+ platforms. contains ( configPlatform) else {
70+ continue
8671 }
8772
88- guard shouldUseThisConfig ( ) else {
73+ /// If prefers universal, skip image config parsing.
74+ if prefersUniversal, configPlatform == . ios || configPlatform == . watchos {
8975 continue
9076 }
9177
92- guard let scaleStr = ( imageConfig [ " scale " ] as? String ) ? . prefix ( 1 ) ,
93- let scale = Float ( scaleStr) ,
94- let sizeStr = ( imageConfig [ " size " ] as? String ) ? . split ( separator: " x " ) [ 0 ] ,
78+ let scaleStr = ( imageConfig [ " scale " ] as? String ) ? . prefix ( 1 ) ?? " 1 "
79+ guard let scale = Float ( scaleStr) ,
80+ let sizeStr = ( imageConfig [ " size " ] as? String ) ? . split ( separator: " x " ) . first ,
9581 let size = Float ( sizeStr) else {
96- continue
97- }
82+ continue
83+ }
9884
99- let newFilename = " AppIcon- \( sizeStr) @ \( scaleStr) x.png "
85+ let newFilename = " AppIcon_ \( sizeStr) @ \( scaleStr) x.png "
10086 let resizeConfig = ResizeConfiguration ( width: Int ( size * scale) , height: Int ( size * scale) , filename: newFilename)
10187 resizeConfigs. append ( resizeConfig)
10288
@@ -105,22 +91,54 @@ public class AssetGenerator {
10591 filteredImageConfigs. append ( mutableImageConfig)
10692 }
10793
94+ /// If prefers universal, generate 1024x1024 images for `ios` and `watchos`.
95+ if prefersUniversal {
96+ for platform in platforms {
97+ guard platform == . ios || platform == . watchos else {
98+ continue
99+ }
100+
101+ let filename = " AppIcon_ \( platform. rawValue) .png "
102+ resizeConfigs. append ( ResizeConfiguration ( width: 1024 , height: 1024 , filename: filename) )
103+ filteredImageConfigs. append ( [
104+ " filename " : filename,
105+ " idiom " : " universal " ,
106+ " platform " : platform. rawValue,
107+ " size " : " 1024x1024 " ,
108+ ] )
109+ }
110+ }
111+
108112 resizeConfigs. forEach { config in
109113 try ? resizeImage ( imageSource: imageSource, resizeConfiguration: config, outputUrl: outputFolder)
110114 }
111115
112116 config [ " images " ] = filteredImageConfigs
113117 try AssetUtils . writeDictionaryToJson ( config, filename: " Contents.json " , url: outputFolder)
118+
119+ print ( " [assetool] IconSet generated at \( outputFolder) " )
120+ }
121+
122+ private func getPlatform( from config: [ String : Any ] ) -> AssetKit . Platform ? {
123+ if ( config [ " idiom " ] as? String ) == " mac " {
124+ return . macos
125+ }
126+ if let platformString = config [ " platform " ] as? String {
127+ if platformString == " ios " {
128+ return . ios
129+ } else if platformString == " watchos " {
130+ return . watchos
131+ }
132+ }
133+ return nil
114134 }
115135
116136 public func generateImageSet( input: NSImage ,
117137 filename: String ,
118138 outputPath: String ,
119139 width: CGFloat ? = nil ,
120140 height: CGFloat ? = nil ) throws {
121- guard let imageSource = AssetUtils . createCGImageSource ( from: input) else {
122- throw AssetGeneratorError . dataSourceError
123- }
141+ let imageSource = try AssetUtils . createCGImageSource ( from: input)
124142 try generateImageSet (
125143 imageSource: imageSource,
126144 filename: filename,
@@ -133,9 +151,7 @@ public class AssetGenerator {
133151 outputPath: String ,
134152 width: CGFloat ? = nil ,
135153 height: CGFloat ? = nil ) throws {
136- guard let imageSource = AssetUtils . createCGImageSource ( from: inputPath) else {
137- throw AssetGeneratorError . dataSourceError
138- }
154+ let imageSource = try AssetUtils . createCGImageSource ( from: inputPath)
139155 try generateImageSet (
140156 imageSource: imageSource,
141157 filename: AssetUtils . extractFilename ( inputPath: inputPath) ,
@@ -149,10 +165,11 @@ public class AssetGenerator {
149165 outputPath: String ,
150166 width: CGFloat ? = nil ,
151167 height: CGFloat ? = nil ) throws {
152- guard let originalSize = AssetUtils . sizeOfImageSource ( imageSource) ,
153- var config = AssetUtils . loadResourceJson ( filename: " image_contents " ) else {
154- throw AssetGeneratorError . resourceError
155- }
168+ guard let originalSize = AssetUtils . sizeOfImageSource ( imageSource) else {
169+ throw AssetGeneratorError . resourceError
170+ }
171+
172+ var config = try AssetUtils . loadResourceJson ( filename: " image_contents " )
156173
157174 // @1x size
158175 var oneXWidth : CGFloat = 0
@@ -213,7 +230,7 @@ public class AssetGenerator {
213230 kCGImageSourceCreateThumbnailWithTransform: true ,
214231 kCGImageSourceShouldCacheImmediately: true ,
215232 kCGImageSourceThumbnailMaxPixelSize: max ( resizeConfiguration. width, resizeConfiguration. height) ,
216- ] as CFDictionary
233+ ] as [ CFString : Any ] as CFDictionary
217234
218235 guard let resized = CGImageSourceCreateThumbnailAtIndex ( imageSource, 0 , options) else {
219236 throw AssetGeneratorError . dataSourceError
0 commit comments