I was surprised to see that Xcode does not make it easy to build all the various icon files for AppIcons for Mac OS and IOS. A few tools have been whipped together, but I’m not a fan of needing to install a whole new GUI app just to solve a simple problem. I’m also not a huge proponent of python, but it’s one of the scripting languages that natively supports JSON — which is part of how Apple’s implemented .xcassets (look inside you’ll see a file called Contents.json). So here is my solution — you’ll need to customize it for your own project. This particular project has two different AppIcon.appiconset entries in the xcassets file.
Note that this script re-writes the Contents.json file, to normalize the file naming. By default if you drag-and-drop files into Xcode it just adds -1 and -2 etc.. to the name, which is lame.
Whenever you update the icon (hardcoded here as a file called ‘icon.pdf’) re-run this script and the icon for you Mac and/or iOS app will update!
import re
import json
from subprocess import call
from pprint import pprint
for iconset in ['Design Show Server/Images.xcassets/AppIcon.appiconset', 'Design Show/Images.xcassets/AppIcon.appiconset']:
json_data=open(iconset + '/Contents.json')
newdata = []
data = json.load(json_data)
for img in data["images"]:
size = int(re.sub(r'x.+$','', img["size"]))
filename='{idiom:s}_{size:d}_{scale}.png'.format(idiom=img["idiom"],scale=img["scale"],size=size)
filepath='{iconset:s}/{filename:s}'.format(iconset=iconset,filename=filename)
if img["scale"] == '2x':
size = size * 2
newdata.append({ "filename" : filename, "size" : img["size"], "idiom" : img["idiom"], "scale" :img["scale"] })
print('{filename:s} {size:d}'.format(filename=filename,size=size))
call(['sips', '-s', 'format', 'png', '-Z', str(size), '-o', filepath, 'icon.pdf'])
json_data.close()
contents_file = open(iconset + '/Contents.json', "w")
contents_file.write( json.dumps({ "images" : newdata, "info" : { "version" : 1, "author" : "andy's python script" }}) )
contents_file.close()
Here’s a gist: