{"_id":"5b720760c44b7600034b79fb","project":"55e67aaa9cc7c62b00c4a1ea","version":{"_id":"5b720760c44b7600034b7a08","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"forked_from":"5b1f2cbdfd653400031d8d9f","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z","categories":["5b720760c44b7600034b79a7","5b720760c44b7600034b79a8","5b720760c44b7600034b79a9","5b720760c44b7600034b79aa","5b720760c44b7600034b79ab","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5b720760c44b7600034b79ac","5b720760c44b7600034b79ad","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"API V6","version_clean":"1.4.0","version":"1.4"},"category":{"_id":"5b720760c44b7600034b79ac","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"version":"5b720760c44b7600034b7a08","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-02-08T21:31:11.878Z","from_sync":false,"order":7,"slug":"advanced-techniques","title":"Advanced Techniques"},"user":"55d29988486de50d00327118","githubsync":"","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-06-28T21:52:17.509Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","apiSetting":null,"auth":"required","params":[],"url":""},"isReference":false,"order":14,"body":"Starting in iOS 10.3, Apps are able to maintain a set alternate icons which can be switched by the user at runtime. Imagine being able to theme your App Icon based on your home team in a sports app? Or have an icon change to reflect a Sale or campaign, such as Halloween?\n\n## Setting up the icons\nFor this new API, you unfortunately cannot use your XCAssets folder. You instead have to import icon assets using an older technique, by creating a group under Resources. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/6c9eb80-Screen_Shot_2017-06-29_at_9.24.03_AM.png\",\n        \"Screen Shot 2017-06-29 at 9.24.03 AM.png\",\n        259,\n        365,\n        \"#f0f0ef\"\n      ],\n      \"caption\": \"We've included a minimal set for brevity, you should include all icons for all size iPhones and iPads.\"\n    }\n  ]\n}\n[/block]\n## Configuring your Property List\nInside your App's `Info.plist` file, add the following config to declare your main icon and it's alternatives. The file name should not include the :::at:::2x/@3x and filetype suffix.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/0b36996-Screen_Shot_2017-06-29_at_9.28.55_AM.png\",\n        \"Screen Shot 2017-06-29 at 9.28.55 AM.png\",\n        666,\n        182,\n        \"#cedbec\"\n      ]\n    }\n  ]\n}\n[/block]\n## Triggering icon changes\n\nNow, the final step is to configure your app to change the icon in a reaction to a push. We'll use [Key-Value Payloads](doc:key-value-payloads) to send down the alternate icon's key (the key for the dictionary above) and use the standard api for receiving pushes to react. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {\\n    guard let iconName = userInfo[\\\"icon_name\\\"] as! String? else {\\n        completionHandler(.noData)\\n        return\\n    }\\n\\n    // We found this delay necessary in testing\\n    delay(1.0, closure: {\\n        self.changeIcon(iconName: iconName)\\n        completionHandler(.newData)\\n    })\\n}\\n\\nfunc changeIcon(iconName: String) {\\n    if #available(iOS 10.3, *) {\\n        if UIApplication.shared.supportsAlternateIcons {\\n            UIApplication.shared.setAlternateIconName(iconName) { (err:Error?) in\\n                print(\\\"Error setting icon: \\\\(String(describing: err))\\\")\\n            }\\n        } else  {\\n            print(\\\"I cannot change icons\\\")\\n        }\\n    }\\n}\\n\\nfunc delay(_ delay:Double, closure:@escaping ()->()) {\\n    let when = DispatchTime.now() + delay\\n    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n## Example\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/d6da21f-IconChangeGif.gif\",\n        \"IconChangeGif.gif\",\n        495,\n        880,\n        \"#38323f\"\n      ]\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"changing-icons-with-push-notifications","type":"basic","title":"iOS: Changing Icons with Push Notifications"}

iOS: Changing Icons with Push Notifications


Starting in iOS 10.3, Apps are able to maintain a set alternate icons which can be switched by the user at runtime. Imagine being able to theme your App Icon based on your home team in a sports app? Or have an icon change to reflect a Sale or campaign, such as Halloween? ## Setting up the icons For this new API, you unfortunately cannot use your XCAssets folder. You instead have to import icon assets using an older technique, by creating a group under Resources. [block:image] { "images": [ { "image": [ "https://files.readme.io/6c9eb80-Screen_Shot_2017-06-29_at_9.24.03_AM.png", "Screen Shot 2017-06-29 at 9.24.03 AM.png", 259, 365, "#f0f0ef" ], "caption": "We've included a minimal set for brevity, you should include all icons for all size iPhones and iPads." } ] } [/block] ## Configuring your Property List Inside your App's `Info.plist` file, add the following config to declare your main icon and it's alternatives. The file name should not include the @2x/@3x and filetype suffix. [block:image] { "images": [ { "image": [ "https://files.readme.io/0b36996-Screen_Shot_2017-06-29_at_9.28.55_AM.png", "Screen Shot 2017-06-29 at 9.28.55 AM.png", 666, 182, "#cedbec" ] } ] } [/block] ## Triggering icon changes Now, the final step is to configure your app to change the icon in a reaction to a push. We'll use [Key-Value Payloads](doc:key-value-payloads) to send down the alternate icon's key (the key for the dictionary above) and use the standard api for receiving pushes to react. [block:code] { "codes": [ { "code": "func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {\n guard let iconName = userInfo[\"icon_name\"] as! String? else {\n completionHandler(.noData)\n return\n }\n\n // We found this delay necessary in testing\n delay(1.0, closure: {\n self.changeIcon(iconName: iconName)\n completionHandler(.newData)\n })\n}\n\nfunc changeIcon(iconName: String) {\n if #available(iOS 10.3, *) {\n if UIApplication.shared.supportsAlternateIcons {\n UIApplication.shared.setAlternateIconName(iconName) { (err:Error?) in\n print(\"Error setting icon: \\(String(describing: err))\")\n }\n } else {\n print(\"I cannot change icons\")\n }\n }\n}\n\nfunc delay(_ delay:Double, closure:@escaping ()->()) {\n let when = DispatchTime.now() + delay\n DispatchQueue.main.asyncAfter(deadline: when, execute: closure)\n}", "language": "swift" } ] } [/block] ## Example [block:image] { "images": [ { "image": [ "https://files.readme.io/d6da21f-IconChangeGif.gif", "IconChangeGif.gif", 495, 880, "#38323f" ] } ] } [/block]