├── .gitignore ├── From Artboards.sketchplugin ├── From Slice.sketchplugin ├── LICENSE ├── README.md └── common.jst /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .project 3 | .settings 4 | -------------------------------------------------------------------------------- /From Artboards.sketchplugin: -------------------------------------------------------------------------------- 1 | // Sketch Plugin: Export to ICNS From Artboards (option shift command a) 2 | // Source: https://github.com/solicomo/export-to-icns 3 | // Version: 0.1.1 4 | // Author: Soli 5 | 6 | @import 'common.jst' 7 | 8 | (function() { 9 | var iconPath = save_path() 10 | var tmpPath = NSTemporaryDirectory() 11 | var guid = [[NSProcessInfo processInfo] globallyUniqueString] 12 | var iconsetPath = [tmpPath stringByAppendingPathComponent: guid + @".iconset"] 13 | var fileManager = [NSFileManager defaultManager] 14 | 15 | [fileManager createDirectoryAtPath:iconsetPath withIntermediateDirectories:true attributes:nil error:nil] 16 | 17 | var artboardCount = [[[doc currentPage] artboards] count] 18 | if (artboardCount < 1) { 19 | [doc showMessage:"Failed: No artboard or slice found."] 20 | return false 21 | } 22 | 23 | var artboards = [[doc currentPage] artboards] 24 | for (var i=0; i < artboardCount; i++) { 25 | var artboard = [artboards objectAtIndex:i] 26 | var artboardName = [artboard name] 27 | var fileName = [iconsetPath stringByAppendingPathComponent: artboardName + ".png"] 28 | 29 | if ([artboardName hasSuffix:@"Lock"]) { 30 | continue 31 | } 32 | 33 | [doc saveArtboardOrSlice:artboard toFile:fileName] 34 | } 35 | 36 | convert_iconset_to_icns(iconsetPath, iconPath) 37 | [fileManager removeItemAtPath:iconsetPath error:nil] 38 | })(); 39 | -------------------------------------------------------------------------------- /From Slice.sketchplugin: -------------------------------------------------------------------------------- 1 | // Sketch Plugin: Export to ICNS From Slice (shift command a) 2 | // Source: https://github.com/solicomo/export-to-icns 3 | // Version: 0.1.1 4 | // Author: Soli 5 | 6 | @import 'common.jst' 7 | 8 | (function() { 9 | var iconPath = save_path() 10 | var tmpPath = NSTemporaryDirectory() 11 | var guid = [[NSProcessInfo processInfo] globallyUniqueString] 12 | var iconsetPath = [tmpPath stringByAppendingPathComponent: guid + @".iconset"] 13 | var pngPath = [tmpPath stringByAppendingPathComponent: guid + @".png"] 14 | var fileManager = [NSFileManager defaultManager] 15 | 16 | [fileManager createDirectoryAtPath:iconsetPath withIntermediateDirectories:true attributes:nil error:nil] 17 | 18 | var slices = [[doc currentPage] exportableLayers] 19 | 20 | if (!slices || [slices count] < 1) { 21 | [doc showMessage:"Failed: No exportable layer found."] 22 | return false 23 | } 24 | 25 | var slice = [slices firstObject] 26 | var sliceCount = [slices count] 27 | 28 | for (var i=0; i < sliceCount; i++) { 29 | var s = [slices objectAtIndex:i] 30 | 31 | if ([s isSelected]) { 32 | slice = s 33 | break 34 | } 35 | } 36 | 37 | if (!slice) { 38 | [doc showMessage:"Failed: No slice found."] 39 | return false 40 | } 41 | 42 | [doc saveArtboardOrSlice:slice toFile:pngPath] 43 | 44 | var pngSizes = [NSDictionary dictionaryWithObjectsAndKeys: 45 | @" 16 16 ", @"icon_16x16.png", 46 | @" 32 32 ", @"icon_16x16@2x.png", 47 | @" 32 32 ", @"icon_32x32.png", 48 | @" 64 64 ", @"icon_32x32@2x.png", 49 | @" 128 128 ", @"icon_128x128.png", 50 | @" 256 256 ", @"icon_128x128@2x.png", 51 | @" 256 256 ", @"icon_256x256.png", 52 | @" 512 512 ", @"icon_256x256@2x.png", 53 | @" 512 512 ", @"icon_512x512.png", 54 | @" 1024 1024 ", @"icon_512x512@2x.png", 55 | nil] 56 | var enumerator = [pngSizes keyEnumerator] 57 | var png = nil 58 | 59 | while (png = [enumerator nextObject]) { 60 | var convertTask = [[NSTask alloc] init] 61 | var convertCmd = "sips -z" + [pngSizes valueForKey:png] + pngPath + " -o " + [iconsetPath stringByAppendingPathComponent:png] 62 | 63 | [convertTask setLaunchPath:"/bin/bash"] 64 | [convertTask setArguments:["-c", convertCmd]] 65 | [convertTask launch] 66 | [convertTask waitUntilExit] 67 | } 68 | 69 | convert_iconset_to_icns(iconsetPath, iconPath) 70 | [fileManager removeItemAtPath:iconsetPath error:nil] 71 | [fileManager removeItemAtPath:pngPath error:nil] 72 | 73 | })(); 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Soli Como 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Export to ICNS 2 | ============== 3 | 4 | A Sketch plugin which can export artboards or slice to ICNS. 5 | 6 | It works both with the sandboxed (from App Store) and standalone versions of Sketch. 7 | 8 | Installation 9 | ------------ 10 | 11 | 1. Download [the latest ZIP file][1] of this plugin. 12 | 2. Extract a folder from the ZIP file and rename it to `Export to ICNS`. 13 | 3. Open Sketch plugins folder. 14 | 15 | You can access the Plugins folder easily by using the `Plugins › 16 | Reveal Plugins Folder` menu option from Sketch. 17 | 18 | 4. Copy the folder `Export to ICNS` to the revealed plugins directory. 19 | 20 | Usage 21 | ----- 22 | 23 | ### Export From Artboards 24 | 25 | 1. Create artboards by going to `File › New From Template › Mac App Icon` in the menu. 26 | 2. Design your icon on these artboards. 27 | 3. Choose `Plugins › Export to ICNS › From Artboards`. 28 | 29 | >Note: You should not rename the artboards. You can prevent individual artboards from exporting by appending `Lock` to the name. 30 | 31 | ### Export From Slice 32 | 33 | 1. Design your icon(s); 34 | 2. Create a slice if you do not want to export the entire artboard; 35 | 3. Select the slice or artboard you want to export; 36 | 4. Choose `Plugins › Export to ICNS › From Slice`. 37 | 38 | >Note: The artboard should not be smaller than 1024x1024, or the hi-res icons will appear blurry. 39 | 40 | Feedback 41 | -------- 42 | 43 | If you have any trouble with this plugin, feel free to [open an issue][2]. 44 | 45 | Credits 46 | ------- 47 | 48 | This plugin is a blend of existing technologies, and has very little original code in it. 49 | Here's what it uses: 50 | 51 | + [Generate ICNS][3], from [Nathan Rutzky](http://nath.co) 52 | + [Sketch Commands][4], from [Ale Muñoz](http://bomberstudios.com) 53 | 54 | [1]: https://github.com/solicomo/export-to-icns/archive/master.zip 55 | [2]: https://github.com/solicomo/export-to-icns/issues 56 | [3]: https://github.com/NathanRutzky/Generate-ICNS 57 | [4]: https://github.com/bomberstudios/sketch-commands 58 | 59 | -------------------------------------------------------------------------------- /common.jst: -------------------------------------------------------------------------------- 1 | // Sketch Plugin: Export to ICNS 2 | // Source: https://github.com/solicomo/export-to-icns 3 | // Version: 0.1.1 4 | // Author: Soli 5 | 6 | function save_path() { 7 | var curPath = [doc fileURL] ? [[[doc fileURL] path] stringByDeletingLastPathComponent] : @"~" 8 | var curName = [[doc displayName] stringByDeletingPathExtension] 9 | var savePanel = [NSSavePanel savePanel] 10 | 11 | [savePanel setTitle:@"Export"] 12 | [savePanel setNameFieldLabel:@"Export To:"] 13 | [savePanel setPrompt:@"Export"] 14 | [savePanel setAllowedFileTypes: [NSArray arrayWithObject:@"icns"]] 15 | [savePanel setAllowsOtherFileTypes:false] 16 | [savePanel setCanCreateDirectories:true] 17 | [savePanel setDirectoryURL:[NSURL fileURLWithPath:curPath]] 18 | [savePanel setNameFieldStringValue:curName] 19 | 20 | if ([savePanel runModal] != NSOKButton) { 21 | exit 22 | } 23 | 24 | return [[savePanel URL] path] 25 | } 26 | 27 | function convert_iconset_to_icns(iconsetPath, iconPath) { 28 | var createCmd = "iconutil -c icns \"" + iconsetPath + "\" -o \"" + iconPath + "\"" 29 | var createTask = [[NSTask alloc] init] 30 | [createTask setLaunchPath:@"/bin/bash"] 31 | [createTask setArguments:["-c", createCmd]] 32 | [createTask launch] 33 | [createTask waitUntilExit] 34 | 35 | if ([createTask terminationStatus] == 0) { 36 | [doc showMessage:@"Done"] 37 | } else { 38 | [doc showMessage:@"Failed:" + [createTask terminationReason]] 39 | } 40 | } 41 | --------------------------------------------------------------------------------