iOS 神奇漏洞,教你如何让 App 图标「动」起来!

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

前几天写了一篇关于如何无缝切换 App Logo 无需系统弹窗的技术文章,感兴趣可以先看看,这篇文章是基于上一篇的。

本篇文章以之前文章为基础,如果还没看过的可以先看之前文章。

为应用配置多 Logo

轻松更换 App 图标,无需系统弹窗!

iOS 漏洞

自从 iOS 10.3 苹果允许开发人员为应用提供替代图标以来,已经有几年时间了,开发者可以配置不同图标供用户选择,相关技术文章可以看我之前发的。

然而,这个功能还比较基础只能在用户点击时设置,而且会有一个系统的弹窗,如果不想有这个弹窗,也可以看上次发的文章,通过一些"手段"来禁止这个弹窗弹出。

目前,除了苹果自带的应用(如时钟和日历)外,没有任何动画或交互式图标------但最近,有研究人员发现了一个可以做动画的漏洞,今天就来讲讲这方面的内容。

后台执行更换图标操作

我们知道设置其他图标是通过 UIApplication.shared .setAlternateIconName 这个 API 进行的,但是这个 API 有一些限制,首先,每次执行之后,都会有一个系统弹窗,经过一些探索,上一篇文章中已经成功跳过了这个限制。

下一个限制是这个 API 无法在后台执行,如果在后台执行就会报错,经过一些探索,系统底层调用的其实是一个名为 LSApplicationProxy 的类,通过调用 LSBundleProxybundleProxyForCurrentProcess 函数来创建了一个可以设置 App Logo 的实例。那么我们为了能够调用这个私有 API,先创建出这两个类的声明:

创建 LSApplicationProxy.h 文件:

objectivec 复制代码
#import <Foundation/Foundation.h>

@interface LSApplicationProxy: NSObject

- (void)setAlternateIconName:(nullable NSString *)name
                  withResult:(void (^_Nonnull)(BOOL success, NSError *_Nullable))result;

@end

创建 LSApplicationProxy.h 文件:

objectivec 复制代码
#import <Foundation/Foundation.h>

@interface LSBundleProxy: NSObject

+ (nonnull LSApplicationProxy *)bundleProxyForCurrentProcess;

@end

然后,在你的应用中创建 LSApplicationProxy 实例:

ini 复制代码
let appProxy: LSApplicationProxy = LSBundleProxy.bundleProxyForCurrentProcess()

在需要替换 App Logo 的地方执行替换方法即可:

lua 复制代码
self.appProxy.setAlternateIconName(selectName) { isSuccess, error  in
    if let error {
        print("设置 App Icon 出错: \(error)")
    } else {
        print("App Icon 设置成功")
    }
}

执行这个方法时,你会发现前台没问题,但是退到后台之后偶尔就无法执行了,为了在后台能够成功替换,我们需要创建一个后台任务,告诉系统,我们需要在后台执行一些代码:

objectivec 复制代码
UIApplication.shared.beginBackgroundTask()

这样代码放到 setAlternateIconName 之前即可。

另外,如果你的代码编译报错,提示无法找到 LSBundleProxy,我们需要告诉编译器我们代码中有这个类,导航到 Build Settings 中,在 Other Linker Flags 中增加:

bash 复制代码
-Wl,-U,_OBJC_CLASS_$_LSBundleProxy

然后运行项目,点击替换 App,然后退到后台,Logo 成功被替换:

让你的 App 图标动起来

既然能够在后台更换图标了,我们想要让图标动起来。简单的方法只需要将一个动画的每一帧做成一张 logo 图片,然后用一个定时器单位时间调用一次修改方法即可。

我这准备了几张 logo,然后 0.5 秒更换一张图片,简单演示一下:

swift 复制代码
class AnimateViewController: UIViewController {
    
    let iconNames = ["AppLogo 0", "AppLogo 1", "AppLogo 2", "AppLogo 3", "AppLogo 4"]
    
    var index = 0
    
    private let appProxy: LSApplicationProxy = LSBundleProxy.bundleProxyForCurrentProcess()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white

        let button = UIButton(type: .system)
        button.setTitle("开始 Logo 动画", for: .normal)
        button.sizeToFit()
        button.addTarget(self, action: #selector(startAnimation), for: .touchUpInside)
        view.addSubview(button)
        button.center = view.center
    }
    
    @objc
    func startAnimation() {
        UIApplication.shared.beginBackgroundTask()
        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
            self.appProxy.setAlternateIconName(self.getLogoName()) { isSuccess, error  in
                if let error {
                    print("设置 App Icon 出错: \(error)")
                } else {
                    print("App Icon 设置成功")
                }
            }
        }
    }
    
    func getLogoName() -> String {
        self.index += 1
        let i = index % 5
        return "AppLogo \(i)"
    }

}

最终效果:

动图不太清楚,可以前往我的视频号查看录屏。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
for_ever_love__14 小时前
UI学习:UICollectionView瀑布流
学习·ui·ios·objective-c·cocoa
大熊猫侯佩18 小时前
WWDC26 全网首发:SwiftUI 8 “可重排序“操作符深度解析
ios·swiftui·swift
邓小乐19 小时前
Workaround: Xcode27 下载iOS 27.0 Simulator
ios·xcode
韩曙亮19 小时前
【Flutter】Flutter 中的 Android / iOS 特殊配置 ① ( 网络权限配置 | HTTP 明文传输配置 | 应用名称配置 )
android·网络·flutter·http·ios·网络权限
人月神话-Lee1 天前
【图像处理】颜色空间——RGB之外的世界
图像处理·人工智能·ios·ai编程·swift·rgb·颜色空间
东坡肘子1 天前
WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139
人工智能·swiftui·swift
CocoaKier1 天前
苹果后台年龄分级填写错误,可能导致审核被拒!
ios·apple
月诸清酒1 天前
Codex 现在能在浏览器里跑 iOS 模拟器了
ios
武子康1 天前
调查研究-159 Apple WWDC 2026 定档 6/8-12:Siri 与 AI 升级,可能是苹果最关键的一次
人工智能·深度学习·ios·ai·chatgpt·apple·wwdc