{"_id":"59542511b330760037c4c792","project":"55e67aaa9cc7c62b00c4a1ea","version":{"_id":"55e67aab9cc7c62b00c4a1ed","project":"55e67aaa9cc7c62b00c4a1ea","__v":10,"createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z","categories":["55e67aac9cc7c62b00c4a1ee","55e67b5556007d23005fee7d","55e67b5dde6fef23009480ca","55e680efde6fef23009480db","55e6829485a9741900314e99","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","589b8e1fdbb7cd190026732c","58b8ca5e3265d70f001788d4"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"category":{"_id":"589b8e1fdbb7cd190026732c","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"version":"55e67aab9cc7c62b00c4a1ed","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-02-08T21:31:11.878Z","from_sync":false,"order":6,"slug":"advanced-techniques","title":"Advanced Techniques"},"user":"55d29988486de50d00327118","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-06-28T21:52:17.509Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":999,"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":"Changing Icons with Push Notifications"}

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]