1. 程式人生 > >動態更新App的圖示(AppIcon)

動態更新App的圖示(AppIcon)

序言

        隨著時代的進步,人的生活多元化。一些公司的 App 也隨著人的生活改變而進行適和情景的變化。比如,本公司的 App 在四月時是本公司成立 4 週年的生日,那就想在本公司 AppIcon 上新增一個聖誕帽。第一種方法: 在 App 的工程中,替換原始的 AppIcon ,再提交 AppStore 進行稽核。這種方法不說麻煩,而且耗費時間長。第二種:在 App 中動態更新 AppIcon 。 這種方法直接、快速、適合即時應用。

1、本部落格介紹方法實現的效果圖如下

效果圖

2、 重點知識點的介紹

@interface UIApplication (UIAlternateApplicationIcons
)
// If false, alternate icons are not supported for the current process. @property (readonly, nonatomic) BOOL supportsAlternateIcons NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2)); // Pass `nil` to use the primary application icon. The completion handler will be invoked asynchronously on an arbitrary background queue; be sure to dispatch back to the main queue before doing any further UI work.
- (void)setAlternateIconName:(nullable NSString *)alternateIconName completionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2)); // If `nil`, the primary application icon is being used.
@property (nullable, readonly, nonatomic) NSString *alternateIconName NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2)); @end

1 / supportsAlternateIcons 函式

      該函式是判斷裝置是否支援備用 AppIcon 的功能。該功能的使用條件是裝置的系統必須是 iOS 10.3 以上的版本。

2 / alternateIconName 引數

      該引數是一個只讀屬性的引數,如果該引數為 nil 時,那App 就會使用預設的AppIcon 。否則,App 使用的是備用AppIcon ,那麼 alternateIconName 獲得的結果就是App 正在使用的備用AppIcon的名子。

3 / setAlternateIconName: completionHandler: 函式

      該函式是執行AppIcon 圖示替換的功能。在進行替換時 App 的系統會彈出一個提示讓你確定是否變更AppIcon 。如果,要自動變更AppIcon ,那麼這個提示就不能出現。對於如何去掉這個提示,後面介紹。

3、使用備用AppIcon需要在工程的 info.plist 檔案中進行配置,配置如下:

工程配置
1、新增流程
  • 我們在工程的 Info.plist 檔案中新增 Icon files(iOS 5)key 。該 key 的型別(Type)為 Dictionary
  • Icon files(iOS 5) 對應的字典,包含 2 個物件分別是: Primary IconNewsstand Icon。 這兩個物件的型別也是 * Dictionary*
  • 我們要使用備用的AppIcon ,那麼我們就要在 Icon files(iOS 5) 對應的字典中,新增一個物件 CFBundleAlternateIcons 物件,該物件的型別是字典(Dictionary)。
  • 我們在CFBundleAlternateIcons 物件中新增備用*AppIcon 的影象物件。如上圖 Icon1Icon2 所示,這兩個物件的型別也是字典。
  • 我們要在新增的AppIcon物件中在新增一個 CFBundleIconFiles 的物件,該物件的型別是陣列(Array)。
  • CFBundleIconFiles 的物件中新增AppIcon 的影象檔名字為元素,該元素的型別是 String,以便後期使用。
2、引數介紹
  • Primary Icon  是預設 AppIcon 的物件。該物件包含 *Icon already includes gloss effectsIcon files 兩個物件。 *Icon already includes gloss effects 是一個布林型別,它表示AppIcon 是否是高光狀態。Icon files 是一個數組物件,它包含預設的AppIcons 的檔名字物件,物件型別是字串(String)。
  • CFBundleAlternateIcons   備用AppIcon 可能有好幾個,那麼CFBundleAlternateIcons 包含的物件就不只一個。我們介紹其中一個例如 Icon1 包含 CFBundleIconFiles 一個存放AppIcon 影象的陣列。陣列內是各個AppIcon 檔案的名字。
  • Newsstand Icon    這是報刊類 Newsstand App 的圖示設定。該物件包含 Binding edgeIcon filesBinding type 三個物件。Binding edge 是一個字串物件,它的作用是設定Newsstand Icon 的位置,可選型別有 leftrightbottomIcon files 是一個數組物件,它裡面存放影象的檔名字。Binding type 是設定Newsstand Icon 歸屬的型別,型別可選有 Magazine*Newspaper

4、 核心程式碼

#pragma mark Change 'AppIcon'
-(void) changeAppIcon:(NSString *) iconName {
    // TODO: Get the App itself
    UIApplication * application = [UIApplication sharedApplication];
    // TODO: Determine whether the device supports' AlternateIcons'
    /**
     *  AlternateIcons : 擴充套件備用圖示。
     *  使用條件: ios10.3 以上的裝置
     */
    if ([application supportsAlternateIcons]) {
        // Change the 'AppIcon'
        [application setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
            // Change the abnormal result of 'AppIcon'
            NSLog(@"%@",error);
        }];
    }
}

App 程式中呼叫上面的函式,就可實現AppIcon的變更。注意,當你呼叫時,系統會彈出一個提示,讓你確定進行AppIcon 的變更操作,確定後AppIcon 才會替換。如下所示:

AppIcon 的變更確認

5、清除變更 AppIcon 時系統彈出框

         我們知道系統的彈出框是由 UIAlertController 來實現的,它屬於一個控制器。在彈出的時候會呼叫 presentViewController:animated:completion:   函式。那我們可以通過這個方法來阻止彈框的彈出。由於蘋果系統的不開放性,我們也沒發更改這個函式。目前,方法就是利用執行時,用我們建立的一個方法來替換這個方法。在我們的方法中來阻止彈框的彈出。

1、核心程式碼

該段程式碼可放在繼承的控制器中或者在控制器中直接寫。匯入執行時的函式庫 #import < objc/runtime.h >

#pragma mark 彈窗的清楚
+(void)load {
    Method  presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
    Method  presentAlternativeM = class_getInstanceMethod(self.class, @selector(clearPresentViewController:animated:completion:));
    // 方法的切換
    method_exchangeImplementations(presentM, presentAlternativeM);
}

#pragma mark 清楚處理方法
-(void)clearPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
    // 跳轉頁面的型別
    if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
        UIAlertController * alertVctl  = (UIAlertController *) viewControllerToPresent ;
        if (alertVctl.title == nil && alertVctl.message == nil) {
            return ;
        }
    }
    // 頁面回撥
    [self clearPresentViewController:viewControllerToPresent animated:flag completion:completion];
}

6、程式碼下載

  • 程式碼下載,可在部落格下留言和郵箱。
  • 可新增QQ:群號:185341804 (成功QQ吧),聯絡群主獲取。