develop

flutter 앱 아이콘 동적으로 변경하기 (시즌 앱 아이콘 iOS, AOS)

방뎁 2024. 11. 22. 21:32

우선 시작하기 전에 

여름용 겨울용 추석용으로 앱 아이콘을 적용할 거라는 좋지 못한 소리를 들었다. 

기획.... 그래 앱 아이콘이 그렇게 중요합니까ㅏㅏㅏ

 

왜 사시사철 다해버리지 흥

 

하여튼, 노비는 일을 해야지

 

우선 구조를 설명하자면, 

flutter 코드에서 날짜를 받아와서 

아이콘을 변경할 날짜와 해당 이미지 이름을 

채널을 통해 전달한다. 

 

그 후 네이티브 소스에서 

OS에 맞게 수정하면 된다. 

 

1. iOS

 

변경해야 하는 파일은 총 2개

- info.plist

- AppDelegate

 

이미지는 기본이미지, 변경될 이미지를 Runner 폴더 아래 위치시키기

+ 아이콘 이름은 @2x, @3x 등 붙여주기 

아이폰

@2x : 120*120

@3x : 180*180

 

아이패드 

ipad@2x : 152*152

ipadPro@2x : 167*167

이미지 옮길 때에는 아래와 같이 설정하여 옮기기

이렇게 세팅해 두면 코드는 간단하다. 

 

 

flutter code

MethodChannel platform = MethodChannel("packageName"); // 고유한 값 넣기 보통 번들ID + ~~ 붙임

Future<void> changeAppIcon() async {
    DateTime now = DateTime.now();
    DateTime startDate = DateTime(2024, 11, 18);
    DateTime endDate = DateTime(2024, 11, 20);

    var isIconNeedChange = (now.isAfter(startDate) &&
        now.isBefore(endDate.add(Duration(days: 1))));

    try {
      final String result = await platform.invokeMethod(
        'changeIcon',
        {'icon_change': isIconNeedChange},
      );
    } on PlatformException catch (e) {
      debugPrint("Failed to change icon: '${e.message}'.");
    }
  }

 

info.plist

 <key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>호출하여 사용할 아이콘 키값</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>변경할 아이콘 파일 이름</string>
                </array>
                <key>UIPrerenderedIcon</key>
                <false/>
            </dict>
            <key>호출하여 사용할 아이콘 키값</key>
            <dict>
                <key>UIPrerenderedIcon</key>
                <false/>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>기본아이콘 파일 이름</string>
                </array>
            </dict>
        </dict>
        <key>CFBundlePrimaryIcon</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <string>기본아이콘 파일 이름</string>
            </array>
            <key>UIPrerenderedIcon</key>
            <false/>
        </dict>
    </dict>

 

AppDelegate

 

objc code

// didFinishLaunchingWithOptions 내부에 해당 코드 작성

FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
    methodChannel = [FlutterMethodChannel methodChannelWithName:@"패키지이름" binaryMessenger:controller];
    [methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    
    if ([@"changeIcon" isEqualToString:call.method]) { 
            if ([call.arguments isKindOfClass:[NSDictionary class]]) {
                NSDictionary *args = (NSDictionary *)call.arguments;
                NSNumber *value = args[@"icon_change"];
                
                if (value != nil && [value isKindOfClass:[NSNumber class]]) {
                    NSLog(@"Received value: %@", value);
                    if ([value boolValue]) {
                        [self setApplicationIconName:@"info.plist에서 설정한 아이콘 키값"];
                    } else {
                        [self setApplicationIconName:nil];
                    }
                }
            }
        } 
    
   }
 
 // --------
   
 
 // MARK: App icon 변경 
- (void)setApplicationIconName:(NSString * _Nullable)iconName {
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] && [[UIApplication sharedApplication] supportsAlternateIcons]) {
        
        typedef void (*setAlternateIconName)(id, SEL, NSString * _Nullable, void (^)(NSError * _Nullable));
        
        NSString *selectorString = @"_setAlternateIconName:completionHandler:";
        SEL selector = NSSelectorFromString(selectorString);
        IMP imp = [[UIApplication sharedApplication] methodForSelector:selector];
        setAlternateIconName method = (setAlternateIconName)imp;
        
        method([UIApplication sharedApplication], selector, iconName, ^(NSError * _Nullable iconChangeError) {
            NSLog(@"===============================");
            NSLog(@"%@", iconChangeError.localizedDescription);
            NSLog(@"===============================");
        });
    }
}

iOS에서 앱 아이콘을 변경하는 건 

사용자의 입력을 받아 변경하는 것이 올바른 사용법이다. 

 

변형하여 사용하기 때문에

리젝 당할 수 있음 -> 그런거 치고는 다른앱들도 많이 씀

 

2. AOS

2024.11.21 - [develop] - Flutter 앱아이콘 동적으로 변경하기 - 안드로이드

 

Flutter 앱아이콘 동적으로 변경하기 - 안드로이드

우선 이 글을 쓰는 목적은3일간 스트레스 받았던 기록을 남겨야겠어서 입니다.  여름, 겨울, 추석 등등 이벤트 용으로 앱 아이콘을 변경해달라는 요청을 받았습니다.  iOS는 무사히 변경했고

devfart.tistory.com