iOSはAppIconを動的に切り替えます

1.需要を見る:フェスティバルの活動中に、一部の大手メーカーのAppIconが自動的に変更されることが通常見られます。また、新しいバージョンを更新せずに、フェスティバル中にユーザーがAppIconを切り替えることができるようにする必要があります。

2.列スキーム:1。ホットアップデート2.リリースバージョンと強制アップデート3.AppIconは自動的に切り替わります。

3.オプション:3

4.特定の実装:

1.画像:画像をプロジェクトリソースフォルダにドラッグし、以下に示すように、エレガントで適切な名前を付けます。

2. Info.plistファイルを構成し、アイコンファイル(iOS 5)を追加します。これは、デフォルトで2つのキー値を持つ辞書です。

**プライマリアイコン(メインアイコン):**アプリのメインアイコンを設定します。ここでアイコンファイル配列に追加できます。複数ある場合は、順番に追加するか、アセットで直接構成できます。ここに入力せずに.xcassets;

**新聞アイコン(ジャーナルアイコン):**すべてのユーザーが購読している新聞や雑誌のアイコンを設定します。現時点では必要ありませんので、気にしないでください。

重要:アイコンファイルにキーを追加します(iOS 5):CFBundleAlternateIcons、タイプは辞書です。****このディクショナリで動的に変更する必要があるすべてのAppIconを構成します。キーはAppIconの名前であり、値はディクショナリです(このディクショナリには、CFBundleIconFiles、値のタイプはArray、およびコンテンツの2つのキーが含まれます)。アイコンの名前です。以下に示すように:

3.コードの記述:私は**** Swiftを使用します。このコードMSObjectTools.exchangeAlternateIcon(withName: iconName)は、コメントアウトされた部分である元のメソッドを置き換えるために使用されます。交換しないと、アイコンが正常に切り替わるたびに、迷惑なポップアッププロンプトが表示されます。IMPをSwiftに置き換える方法が見つかりませんでした。そこで、OCクラスが導入されました。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        ///注册后端云
        self.registerLearnCloud()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            self .changeAppIcon(with: "appIcon_earth")
        }
        
        return true
    }
复制代码

アイコンを変更する方法

///更换图标方法
func changeAppIcon(with name: String?) {
        guard UIApplication.shared.supportsAlternateIcons else {
            return
        }
        
        guard let iconName = name, iconName.count > 0 else {
            return
        }
        
        MSObjectTools.exchangeAlternateIcon(withName: iconName)
        
//        UIApplication.shared.setAlternateIconName(iconName) { error in
//            print("切换图标出错,原因:\(error.debugDescription)")
//        }
    }
复制代码

IMPメソッドの置き換え

#import <UIKit/UIKit.h>
#import "MSObjectTools.h"

@implementation MSObjectTools


///执行换图标的方法
+ (void)exchangeAlternateIconWithName:(NSString *)iconName {
    
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] &&
        [[UIApplication sharedApplication] supportsAlternateIcons])
    {
        NSMutableString *selectorString = [[NSMutableString alloc] initWithCapacity:40];
        [selectorString appendString:@"_setAlternate"];
        [selectorString appendString:@"IconName:"];
        [selectorString appendString:@"completionHandler:"];
        
        SEL selector = NSSelectorFromString(selectorString);
        IMP imp = [[UIApplication sharedApplication] methodForSelector:selector];
        void (*func)(id, SEL, id, id) = (void *)imp;
        if (func)
        {
            func([UIApplication sharedApplication], selector, iconName, ^(NSError * _Nullable error) {});
        }
    }
    
}

@end
复制代码

4.注:

  • 1,不能在didFinishLaunchingWithOptions调用这个方法,如果必须在didFinishLaunchingWithOptions里调用的话,必须加延时,否则会报被取消Error

  • 2,setAlternateIconName 这个方法在10.3以后才有,注意系统版本。

  • 3,icon资源文件需要在项目目录下,不能是Assets.xcassets中的图片,否则无效。

后续优化:

我在调用 func changeAppIcon(with name: String?)    这个方法之后,活动结束,发现无法还原。于是做出了如下优化,把完成结果通过block回调出来:

///执行换图标的方法
+ (void)exchangeAlternateIconWithName:(NSString *)iconName completeBlock:(void (^)(NSError * _Nullable error))completed {
    
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] &&
        [[UIApplication sharedApplication] supportsAlternateIcons])
    {
        NSMutableString *selectorString = [[NSMutableString alloc] initWithCapacity:40];
        [selectorString appendString:@"_setAlternate"];
        [selectorString appendString:@"IconName:"];
        [selectorString appendString:@"completionHandler:"];
        
        SEL selector = NSSelectorFromString(selectorString);
        IMP imp = [[UIApplication sharedApplication] methodForSelector:selector];
        void (*func)(id, SEL, id, id) = (void *)imp;
        if (func)
        {
            func([UIApplication sharedApplication], selector, iconName, ^(NSError * _Nullable error) {
                completed(error);
            });
        }
    }
    
}
复制代码

调用的时候

///更换系统图标
    func changeAppIcon(with name: String?) {
        
        if name == UserDefaults.MSOtherRecordInfo.string(forKey: .autoAppIcon) {
            return
        }
        
        if #available(iOS 10.3, *) {
            
            guard UIApplication.shared.supportsAlternateIcons else {
                return
            }

            guard let iconName = name, iconName.count > 0 else {
                return
            }
            
            MSObjectTools.exchangeAlternateIcon(withName: iconName) { error in
                if error == nil {
                    UserDefaults.MSOtherRecordInfo.set(stringValue: iconName, forKey: .autoAppIcon)
                }
            }
        }
    }
复制代码

先在UserDefault里记录下替换AppIcon的图片名称,如果名称相同的话,就不再进行替换了

如果活动结束,想换回之前的,需要一张和AppIcon同样的图片。比如我的appIcon_earth是活动期间的用的,appIcon_default是和App主图标一样的图片。如果活动结束,后台接口把图片名字配置成appicon_default,就OK了。

おすすめ

転載: juejin.im/post/7087488058878066702
おすすめ