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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
若水无华41 分钟前
fiddler 配置ios手机代理调试
ios·智能手机·fiddler
不二狗1 小时前
每日算法 -【Swift 算法】Two Sum 问题:从暴力解法到最优解法的演进
开发语言·算法·swift
Aress"2 小时前
【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
ios·uni-app·ipa安装
Jouzzy11 小时前
【iOS安全】Dopamine越狱 iPhone X iOS 16.6 (20G75) | 解决Jailbreak failed with error
安全·ios·iphone
瓜子三百克12 小时前
采用sherpa-onnx 实现 ios语音唤起的调研
macos·ios·cocoa
左钦杨12 小时前
IOS CSS3 right transformX 动画卡顿 回弹
前端·ios·css3
努力成为包租婆14 小时前
SDK does not contain ‘libarclite‘ at the path
ios
安和昂1 天前
【iOS】Tagged Pointer
macos·ios·cocoa
I烟雨云渊T2 天前
iOS 阅后即焚功能的实现
macos·ios·cocoa
struggle20252 天前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift