iOS動態更換App圖標-踩坑

聲明:
轉載請注明出處:http://www.lxweimin.com/p/9c78f161eeb8
評論請到原文,轉載一概不回復

iOS動態更換App圖標方法就不說了,這里給一篇詳細的介紹文章:iOS動態更換App圖標(一):基礎使用
這里只說一下遇到的坑

坑1

setAlternateIconName不能在didFinishLaunchingWithOptions中調用,會報3072錯誤,需要在ViewController中調用,初步猜想可能是需要window初始化成功后調用,需要一個ViewController或者是UINavigationController之類的,沒有去驗證

坑2

supportsAlternateIcons只是檢測是否能進行更換,并不能進行系統版本號判斷,需要自己進行版本判斷,要不然在低版本系統中會崩潰,比如:iOS7

坑3

icon資源文件需要在項目目錄下,不能是Assets.xcassets中的圖片,否則無效

技巧點1

動態更換App圖標會有彈框,這個可以去掉,教程:iOS動態更換App圖標(二):無彈框更換App圖標
其實不用非要使用擴展,寫在調用setAlternateIconNameViewController里面就可以了,在調用setAlternateIconName前使用代碼

Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(dy_presentViewController:animated:completion:));
// 交換方法實現
method_exchangeImplementations(presentM, presentSwizzlingM);

比如:

- (void)viewDidLoad {
    [super viewDidLoad];
    Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
    Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(dy_presentViewController:animated:completion:));
    // 交換方法實現
    method_exchangeImplementations(presentM, presentSwizzlingM);
    NSString *alternateIconName = [[UIApplication sharedApplication] alternateIconName];
    if (alternateIconName) {
        //重置到默認icon
        [self setAppIconWithName:nil];
    } else {
        NSString *IconName = @"AppIcon-1";
        [self setAppIconWithName:IconName];
    }
}
- (void)setAppIconWithName:(NSString *)iconName {
    if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
        return;
    }
    
    if ([iconName isEqualToString:@""]) {
        iconName = nil;
    }
    [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
        if (error) {
            NSLog(@"更換app圖標發生錯誤了:\n%@",error);
        }
    }];
}
- (void)dy_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    
    if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
        NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);
        NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);
        
        UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
        if (alertController.title == nil && alertController.message == nil) {
            return;
        } else {
            [self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
            return;
        }
    }
    
    [self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
}

技巧點2

plistCFBundleIcons中不需要設置默認圖片,只需要設置替換的圖片就可以了,UIPrerenderedIcon也不需要設置,這個是iOS7之前的參數(如果你現在還在支持iOS6,我只能說上帝保佑你,可憐的孩子!),比如:

    <key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>AppIcon-1</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>AppIcon-1</string>
                </array>
            </dict>
        </dict>
    </dict>

使用的時候參考我上面提供的代碼就行了

我只是粗略測試了一下,如果有出錯的地方謝謝大家指出來

另外如果想在編譯的時候就把圖標替換了,可以使用腳本來做,這樣就不能在運行時替換了

--------------------6.7
附上jenkins打包替換圖標方法,沒寫過jenkins腳本的就要看了,我寫的比較粗略


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,251評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,460評論 25 708
  • 武漢的風,擄走了武漢的春,扔來了武漢的冬。 倘若風如你,必不欺我冬無衣! 這是我來武漢的第三個冬天,也可能是我在武...
    星夜日暘閱讀 172評論 0 0
  • 嗅過鉛華染成的墨香,你是否會想起那些與文字結緣的人付之梨棗前的模樣? “你因夢想而在這個世上受苦,就像一條河流,因...
    伊伊烑閱讀 561評論 0 0
  • 相信很多人都看見過電動摩托車,就是在三四線城市里,滿大街都是大姨大媽們買菜代步的交通工具。但是今天我們要介紹的是一...
    小賽TT閱讀 4,548評論 0 0