This is the 14th day of my participation in the Gwen Challenge.More article challenges

Do you see this feature?

For those of you who use GitHub on your iPhone, have you noticed the following feature:

In the Settings of this App, you can change the App icon.

There’s also a wallpaper App called Cuto that does this. Cuto needs Vip users to use this function, in fact, it is really very common code is very common Api.

When I saw this feature, I was shocked. What kind of hook technology is this?

Interested, I went to the documentation to find out: iOS 10.3 has added a new feature for changing app ICONS, allowing developers to choose from multiple ICONS for their apps.

Harm! It turns out that the system Api is working, and it’s still after iOS10.3, so I have only myself to blame. Not much to say, the code to go up in situ!

Configuration and Use

    1. First, select a good picture material, cut the picture, rename.

    1. Do this in the info.plist file.

Plist file configuration, add Icon Files (iOS 5) type Dictionary.

Note: Open Icon Files (iOS 5), there are two keys: Primary Icon and Newsstand Icon. The pictures in Primary Icon are the default pictures of AppIcon. Don’t worry about this place.

Create a CFBundleAlternateIcons with type Dictionary in Icon Files (iOS 5).

This is a bit complicated to configure, so I’ll go directly to the INFo.plist XML to make it easier to understand, just CV the following code into the info.plist source code.

<key>LSApplicationCategoryType</key>
	<string></string>
	<key>CFBundleIcons</key>
	<dict>
		<key>CFBundlePrimaryIcon</key>
		<dict>
			<key>CFBundleIconFiles</key>
			<array>
				<string></string>
			</array>
		</dict>
		<key>CFBundleAlternateIcons</key>
		<dict>
			<key>blackDuck</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>blackDuck-20</string>
					<string>blackDuck-29</string>
					<string>blackDuck-40</string>
					<string>blackDuck-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>blackSeele</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>blackSeele-20</string>
					<string>blackSeele-29</string>
					<string>blackSeele-40</string>
					<string>blackSeele-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>flowerWeddingRita</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>flowerWeddingRita-20</string>
					<string>flowerWeddingRita-29</string>
					<string>flowerWeddingRita-40</string>
					<string>flowerWeddingRita-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>FlowerWeddingSakura</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>FlowerWeddingSakura-20</string>
					<string>FlowerWeddingSakura-29</string>
					<string>FlowerWeddingSakura-40</string>
					<string>FlowerWeddingSakura-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>fuHua</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>fuHua-20</string>
					<string>fuHua-29</string>
					<string>fuHua-40</string>
					<string>fuHua-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>grandmother</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>grandmother-20</string>
					<string>grandmother-29</string>
					<string>grandmother-40</string>
					<string>grandmother-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>himeko</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>himeko-20</string>
					<string>himeko-29</string>
					<string>himeko-40</string>
					<string>himeko-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>iceDuck</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>iceDuck-20</string>
					<string>iceDuck-29</string>
					<string>iceDuck-40</string>
					<string>iceDuck-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
			<key>whiteSeele</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>whiteSeele-20</string>
					<string>whiteSeele-29</string>
					<string>whiteSeele-40</string>
					<string>whiteSeele-60</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<false/>
			</dict>
		</dict>
	</dict>
Copy the code
    1. Here I click through the tableView to switch AppIcon, simple logic, directly on the code.
import UIKit class ViewController: UIViewController { let sizeString = "-60" lazy var dataSource: [(String, String)] = [(title: "himeko", imageName: "himeko"), (title: "whiteSeele"), (title: "whiteSeele") "FlowerWeddingRita ", imageName: "fuHua", (title:" black ", imageName: "fuHua"), (title: "black ", imageName: "BlackSeele "), (title: "blackDuck", imageName: "blackDuck"), (title:" flowers marry ourei ", imageName: "FlowerWeddingSakura"), (title: ", imageName: "iceDuck"), (title: "grandmother", imageName: "grandmother"),] private lazy tableView: UITableView = { let tableView = UITableView(frame: view.frame, style: .plain) tableView.delegate = self tableView.dataSource = self tableView.register(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell") tableView.tableFooterView = UIView(frame: CGRect.zero) tableView.rowHeight = 66 return tableView }() override func viewDidLoad() { super.viewDidLoad() setUpUI() } Private func setUpUI() {view.backgroundcolor =.white title = "replace AppIcon" view.addSubView (tableView)} @objc private func changeAppIcon(iconName: String) { let app = UIApplication.shared if app.supportsAlternateIcons { app.setAlternateIconName(iconName, completionHandler: { (error) in if error ! = nil { print("error => \(String(describing: error? .localizedDescription))") }else { print("Done") } }) } } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataSource.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) cell.textLabel?.text = dataSource[indexPath.row].0 cell.imageView?.image = UIImage(named: dataSource[indexPath.row].1 + sizeString) return cell } } extension ViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: false) let iconName = dataSource[indexPath.row].1 changeAppIcon(iconName: iconName) } }Copy the code

The core Api is the following methods on uiApplication.shared:

// Pass `nil` to use the primary application icon. The completion handler will be invoked asynchronously on an arbitrary  background queue; Be sure to dispatch back to the main queue before doing any further UI work. @available(iOS 10.3, *) open func setAlternateIconName(_ alternateIconName: String? , completionHandler: ((Error?) -> Void)? = nil)Copy the code

Well, to be honest I am more tired of cutting images and renaming than writing code!!

Finally, a rendering

Did you Get the root of this technique? Can a fierce operation such as tiger, the next door is greedy?

Github resources:

Considering that the configuration of the info.plist file in this place is quite complicated, we are sorting out the code now, and the project link will be attached after completion, please calm down.

Question to consider: Why don’t many apps integrate the ability to change App ICONS? 🤔

Simple configuration, simple Api, basically no technical difficulties to write, but you can see how few apps on the market integrate this feature, right?

App ICONS are updated as quickly as Taobao, but they only change the background color and subtitle on 618 and Double 11, and seldom change the Tao character. From the perspective of products, App ICONS are the entrance for users to click, so they need to have certain recognition and brand effect.

For example, if you use an App and think it is very good and want to recommend it to people around you, a bright App icon with little change is the most important. On the contrary, if an App icon is changed frequently, who will remember it?

This is just a little thought on my part. What do you think?

Tomorrow to continue

Did everyone have a good rest on the last day of Dragon Boat Festival? Tomorrow will go to work, everyone come on!

Besides, I haven’t been captain for years!