@@ -82,7 +82,7 @@ - (NSString *) productName
8282 return productName;
8383}
8484
85- - (NSString *) processAssets
85+ - (NSString *) discoverAppIcon
8686{
8787 NSFileManager *mgr = [NSFileManager defaultManager ];
8888 NSString *filename = nil ;
@@ -113,28 +113,49 @@ - (NSString *) processAssets
113113 break ;
114114 }
115115 }
116+ }
116117
117- // Copy icons to resource dir...
118- GSXCBuildContext *context = [GSXCBuildContext sharedBuildContext ];
119- NSString *productOutputDir = [context objectForKey: @" PRODUCT_OUTPUT_DIR" ];
120- NSString *resourcesDir = [productOutputDir stringByAppendingPathComponent: @" Resources" ];
121- NSString *imagePath = [appIconDir stringByAppendingPathComponent: filename];
122- NSString *destPath = [resourcesDir stringByAppendingPathComponent: filename];
123-
124- // Copy the item, remove it first to make sure there is no issue.
125- // [mgr removeItemAtPath: destPath
126- // error: NULL];
127-
128- [mgr copyItemAtPath: imagePath
129- toPath: destPath
130- error: NULL ];
118+ return filename;
119+ }
120+
121+ - (BOOL ) copyAppIconToResources : (NSString *)iconFilename
122+ {
123+ if (iconFilename == nil )
124+ {
125+ return NO ;
131126 }
132127
128+ NSFileManager *mgr = [NSFileManager defaultManager ];
129+ NSString *productName = [_target name ];
130+ NSString *assetsDir = [productName stringByAppendingPathComponent: @" Assets.xcassets" ];
131+ NSString *appIconDir = [assetsDir stringByAppendingPathComponent: @" AppIcon.appiconset" ];
132+
133+ // Copy icons to resource dir...
134+ GSXCBuildContext *context = [GSXCBuildContext sharedBuildContext ];
135+ NSString *productOutputDir = [context objectForKey: @" PRODUCT_OUTPUT_DIR" ];
136+ NSString *resourcesDir = [productOutputDir stringByAppendingPathComponent: @" Resources" ];
137+ NSString *imagePath = [appIconDir stringByAppendingPathComponent: iconFilename];
138+ NSString *destPath = [resourcesDir stringByAppendingPathComponent: iconFilename];
139+
140+ // Copy the item, remove it first to make sure there is no issue.
141+ // [mgr removeItemAtPath: destPath
142+ // error: NULL];
143+
144+ return [mgr copyItemAtPath: imagePath
145+ toPath: destPath
146+ error: NULL ];
147+ }
148+
149+ - (NSString *) processAssets
150+ {
151+ NSString *filename = [self discoverAppIcon ];
152+ [self copyAppIconToResources: filename];
133153 return filename;
134154}
135155
136156- (BOOL ) processInfoPlistInput : (NSString *)inputFileName
137157 output : (NSString *)outputFileName
158+ withIconFile : (NSString *)iconFileName
138159{
139160 if (inputFileName != nil )
140161 {
@@ -145,11 +166,10 @@ - (BOOL) processInfoPlistInput: (NSString *)inputFileName
145166 NSString *inputFileString = [NSString stringWithContentsOfFile: inputFileName];
146167 NSString *outputFileString = [inputFileString stringByReplacingEnvironmentVariablesWithValues ];
147168 NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithDictionary: [outputFileString propertyList ]];
148- NSString *filename = [self processAssets ];
149169
150- if (filename != nil )
170+ if (iconFileName != nil )
151171 {
152- [plistDict setObject: filename forKey: @" NSIcon" ];
172+ [plistDict setObject: iconFileName forKey: @" NSIcon" ];
153173 }
154174
155175 [plistDict writeToFile: outputFileName
@@ -178,6 +198,16 @@ - (BOOL) processInfoPlistInput: (NSString *)inputFileName
178198 return YES ;
179199}
180200
201+ // Backward compatibility method
202+ - (BOOL ) processInfoPlistInput : (NSString *)inputFileName
203+ output : (NSString *)outputFileName
204+ {
205+ NSString *iconFile = [self processAssets ];
206+ return [self processInfoPlistInput: inputFileName
207+ output: outputFileName
208+ withIconFile: iconFile];
209+ }
210+
181211- (BOOL ) copyResourceFrom : (NSString *)srcPath to : (NSString *)dstPath
182212{
183213 BOOL result = NO ;
@@ -207,7 +237,7 @@ - (BOOL) copyResourceFrom: (NSString *)srcPath to: (NSString *)dstPath
207237 return result;
208238}
209239
210- - (NSMutableDictionary *) configToInfoPlist : (XCBuildConfiguration *)config
240+ - (NSMutableDictionary *) configToInfoPlist : (XCBuildConfiguration *)config withIconFile : ( NSString *) iconFile
211241{
212242 NSMutableDictionary *ipd = [NSMutableDictionary dictionary ];
213243 NSDictionary *buildSettings = [config buildSettings ];
@@ -217,21 +247,23 @@ - (NSMutableDictionary *) configToInfoPlist: (XCBuildConfiguration *)config
217247 NSString *mainNib = [buildSettings objectForKey: @" INFOPLIST_KEY_NSMainNibFile" ];
218248 NSString *principalClass = [buildSettings objectForKey: @" INFOPLIST_KEY_NSPrincipalClass" ];
219249 NSString *bundleIdentifier = [buildSettings objectForKey: @" PRODUCT_BUNDLE_IDENTIFIER" ];
220- NSString *iconFile = [self processAssets ];
221250
222251 [ipd setObject: version forKey: @" CFBundleVersion" ];
223252 [ipd setObject: mainNib forKey: @" NSMainNibFile" ];
224253 [ipd setObject: copyright forKey: @" NSHumanReadableCopyright" ];
225254 [ipd setObject: principalClass forKey: @" NSPrincipalClass" ];
226- [ipd setObject: iconFile forKey: @" NSIcon" ];
255+ if (iconFile != nil )
256+ {
257+ [ipd setObject: iconFile forKey: @" NSIcon" ];
258+ }
227259 [ipd setObject: @" $(DEVELOPMENT_LANGUAGE)" forKey: @" CFBundleDevelopmentRegion" ];
228260 [ipd setObject: @" $(EXECUTABLE_NAME)" forKey: @" CFBundlExecutable" ];
229261 [ipd setObject: bundleIdentifier forKey: @" CFBundleIdentifier" ];
230262
231263 return ipd;
232264}
233265
234- - (NSString *) generateInfoPlistOutput : (NSString *)outputPlist
266+ - (NSString *) generateInfoPlistOutput : (NSString *)outputPlist withIconFile : ( NSString *) iconFile
235267{
236268 GSXCBuildContext *context = [GSXCBuildContext sharedBuildContext ];
237269 // NSString *productOutputDir = [context objectForKey: @"PRODUCT_OUTPUT_DIR"];
@@ -251,19 +283,27 @@ - (NSString *) generateInfoPlistOutput: (NSString *)outputPlist
251283 }
252284
253285 [self processInfoPlistInput: infoPlist
254- output: outputPlist];
286+ output: outputPlist
287+ withIconFile: iconFile];
255288 }
256289 else
257290 {
258291 xcputs ([[NSString stringWithFormat: @" \t * Generating info plist --> %s %@ %s " , GREEN, outputPlist, RESET] cString ]);
259292 XCBuildConfiguration *config = [xcl configurationWithName: @" Debug" ];
260- NSMutableDictionary *ipl = [self configToInfoPlist: config];
293+ NSMutableDictionary *ipl = [self configToInfoPlist: config withIconFile: iconFile ];
261294 pl = [ipl description ];
262295 }
263296
264297 return pl;
265298}
266299
300+ // Backward compatibility method
301+ - (NSString *) generateInfoPlistOutput : (NSString *)outputPlist
302+ {
303+ NSString *iconFile = [self processAssets ];
304+ return [self generateInfoPlistOutput: outputPlist withIconFile: iconFile];
305+ }
306+
267307- (BOOL ) build
268308{
269309 NSFileManager *mgr = [NSFileManager defaultManager ];
@@ -382,8 +422,16 @@ - (BOOL) build
382422 }
383423 }
384424
385- // Handle Info.plist....
386- NSString *pl = [self generateInfoPlistOutput: outputPlist];
425+ // Handle Info.plist....
426+ // Discover and copy app icon first
427+ NSString *iconFile = [self discoverAppIcon ];
428+ if (iconFile != nil )
429+ {
430+ [self copyAppIconToResources: iconFile];
431+ }
432+
433+ // Generate Info.plist with the discovered icon
434+ NSString *pl = [self generateInfoPlistOutput: outputPlist withIconFile: iconFile];
387435 BOOL f = [pl writeToFile: outputPlist atomically: YES ];
388436 if (f == NO )
389437 {
@@ -480,23 +528,29 @@ - (BOOL) generate
480528 [resources addObject: filePath];
481529 }
482530
483- // Handle Info.plist...
484- /*
485- NSDictionary *ctx = [context currentContext] ;
486- XCConfigurationList *xcl = [ctx objectForKey: @"buildConfig" ];
487- XCBuildConfiguration *xbc = [xcl defaultConfiguration ];
488- NSDictionary *bs = [xbc buildSettings];
489- NSString *inputPlist = [bs objectForKey: @"INFOPLIST_FILE"];
490- if ([mgr fileExistsAtPath: inputPlist] == NO )
531+ // Discover app icon separately from Info.plist generation
532+ NSString *iconFile = [ self discoverAppIcon ];
533+ xcputs ([[ NSString stringWithFormat: @" \t * Discovered app icon: %@ " , iconFile ? iconFile : @" (none) " ] cString ]) ;
534+ NSString *appIconPath = [iconFile stringByDeletingFirstPathComponent ];
535+ [resources addObject: appIconPath ];
536+
537+ // Copy app icon to resources if found
538+ if (iconFile != nil )
491539 {
492- inputPlist = [inputPlist lastPathComponent];
540+ BOOL iconCopied = [self copyAppIconToResources: iconFile];
541+ if (iconCopied)
542+ {
543+ xcputs ([[NSString stringWithFormat: @" \t * Copied app icon to resources: %@ " , iconFile] cString ]);
544+ }
545+ else
546+ {
547+ xcputs ([[NSString stringWithFormat: @" \t * Failed to copy app icon: %@ " , iconFile] cString ]);
548+ }
493549 }
494- */
495550
551+ // Generate Info.plist with the discovered icon
496552 NSString *outputPlist = [NSString stringWithFormat: @" %@ Info.plist" ,appName] ;
497- // [self processInfoPlistInput: inputPlist
498- // output: outputPlist];
499- NSString *pl = [self generateInfoPlistOutput: outputPlist];
553+ NSString *pl = [self generateInfoPlistOutput: outputPlist withIconFile: iconFile];
500554 BOOL f = [pl writeToFile: outputPlist atomically: YES ];
501555 if (f == NO )
502556 {
0 commit comments