iOS 10.3 앱 아이콘 동적으로 변경하기
iOS 10.3에 예상치 못한 신규기능중 앱 아이콘을 변경하는 기능이 있습니다. 이번글에서는 이 신규기능을 활용하는 방법과 적용하지 못하는 경우를 적어볼려고 합니다.
MLB At Bat 앱에서 이 기능을 적용했는데요. 자신이 좋아하는 팀 로고로 앱 아이콘을 변경 할 수 있게 했습니다.

MLB At Bat 앱 아이콘 변경
이 포스트의 내용은 영상으로도 촬영 했으니 영상도 참고하시면 동작하는 방식을 이해하기 더 쉬우실거에요
기능을 적용하는것은 정말 간단합니다. 우선 기존에 있던 프로젝트에 새로 추가할 앱 아이콘 이미지를 추가합니다. 예시의 경우 [email protected], [email protected] 파일을 추가했습니다.

앱 아이콘 추가
여기서 이미지를 Assets.xcassets 에 추가하면 안됩니다. 에셋에 추가해서 사용하고 싶어서 시도를 해봤는데 동작하지 않는것을 확인했습니다.
이미지를 추가 했으면 Info.plist 파일에 추가한 아이콘 이미지에 대한 정보를 등록합니다.

Info.plist 파일에 추가할 내용
Xcode 의 Property Editor 에서 자동 완성되지 않는 항목들이라 위와 같은 구조로 일일이 입력해줘야 하는 번거로움이 있습니다.
“Icon files (iOS 5)” 키를 추가하고 그 밑에 “CFBundleAlternateIcons”를 “Dicionary” 타입으로 추가합니다. 그리고 나서 앞으로 변경 가능한 앱 아이콘 후보 이름을 적어 주는데요. 위의 경우 “bundang”, “jeongja” 라는 2개의 앱 아이콘 후보를 추가했습니다.
그리고 각각의 앱 아이콘 후보 이름 밑에는 “CFBundleIconFiles” 라는 “Array” 타입의 키를 추가하고 해당 항목 밑에 실제 앱 아이콘 후보의 이미지 파일명을 적으면 됩니다.
여기서 중요한건 실제 추가한 앱의 파일 이름과 소스코드에서 지정할 파일 이름이 달라도 된다는건데요. 위의 경우 실제 추가한 이미지 파일은 daangn_jeongj[email protected] 인데 이 파일에 해당하는 소스코드에서 참고할 이름은 “jeongja” 입니다.
Info.plist 에 추가한 항목의 XML 소스코드는 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>bundang</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>daangn_bundang</string>
<string>daangn_bundang-72</string>
<string>daangn_bundang-Small</string>
</array>
</dict>
<key>jeongja</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>daangn_jeongja</string>
<string>daangn_jeongja-72</string>
<string>daangn_jeongja-Small</string>
</array>
</dict>
</dict>
</dict>
.... 생략
이제 소스코드에서 앱 아이콘을 변경하고자 하는 부분에 아래 코드를 입력합니다
UIApplication.shared.setAlternateIconName("jeongja") { (error) in
debugPrint("error \(error)")
}
위 코드가 실행되면 앱 아이콘이 변경됩니다. 마지막에 실행되는 코드 블럭은 실행완료후에 호출되는데 error 가 nil 인 경우 성공한것이고 그렇지 않은 경우 변경에 실패한것입니다.

앱 아이콘 변경 확인
앱 아이콘 변경코드가 호출되면 위와 같이 사용자에게 알려주는 팝업이 실행되는데요. 이 팝업은 무조건 보여지는 거라 보이지 않도록 할 방법은 없습니다.
앱 아이콘 변경을 하다보면 안되는 경우를 몇가지 발견하게 되는데요.
첫째, 메인스레드에서 코드가 호출되지 않는 경우 앱 아이콘 변경이 되지 않습니다. 메인스레드가 아닌경우 complete 블럭에서 error에 다음과 같은 객체가 전송됩니다.
"Error Domain=NSCocoaErrorDomain Code=3072 \"작업이 취소되었습니다.\"" 아이폰 시스템 언어가 영어일 경우 아래 메시지 "Error Domain=NSCocoaErrorDomain Code=3072 \"The operation was cancelled.\""
이때는 메인 스레드에서 실행되도록 다음과 같이 수정합니다.
DispatchQueue.main.async {
UIApplication.shared.setAlternateIconName("jeongja") { (error) in
debugPrint("error \(error)")
}
}
둘째, 앱이 foreground 에서 실행중이지 않을때는 앱 아이콘을 변경할 수 없습니다. 이는 사용자 몰래 앱 아이콘이 변경되는것을 막기위한 조치라고 생각됩니다.
셋째, 에셋으로 이미지 추가가 안되다보니 아이패드를 지원하는 경우 예전에 아이콘 추가하던 방식대로 앱 아이콘 이미지 파일의 이름을 맞춰야합니다. 위의 예시에서 daangn_jeongja-72 라고 하는식으로 뒤에 suffix 를 예전에 하던대로 맞춰야하는거죠. 파일 이름 규칙은 애플문서(App Icons on iPhone, iPad and Apple Watch)를 참고 하세요.
참고자료
- 【Swift, iOS10.3】アプリアイコンを動的変更できるalternateIconName
- Swift World: Change your app’s icon programmatically in iOS 10.3
게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^