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

相关推荐
恋猫de小郭13 小时前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨17 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
威化饼的一隅17 小时前
【多模态】swift-3框架使用
人工智能·深度学习·大模型·swift·多模态
福大大架构师每日一题18 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
BangRaJun2 天前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈2 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长2 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
一如初夏丿2 天前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
杨武博2 天前
ios 混合开发应用白屏问题
ios
BangRaJun3 天前
LNCollectionView
android·ios·objective-c