Получите изображение значка в высоком разрешении как UIImage в iOS 18

До iOS 18 у меня был следующий код, который работал хорошо:

    let icons = Bundle.main.infoDictionary!["CFBundleIcons"] as! [String: Any]
    let primaryIcon = icons["CFBundlePrimaryIcon"] as! [String: Any]
    let iconName = primaryIcon["CFBundleIconName"] as! String
    return UIImage(named: iconName)!

iconName — это "AppIcon", и он возвращает изображение размером 1024x1024. Теперь, используя базовый SDK iOS 18, UIImage(named: iconName) равен нулю, что приводит к сбою в моем приложении.

Более подробная информация:

  • Если я создаю базовый SDK iOS 17, он отлично работает как на iOS 17, так и на iOS 18.
  • Если я создаю с использованием базового SDK iOS 18 (с целью развертывания iOS 17), происходит сбой как на iOS 17, так и на iOS 18.

Я попробовал ответы из раздела Как получить UIImage AppIcon?, но результат не такой хороший. В частности, следующий код, в котором используется CFBundleIconFiles вместо CFBundleIconName:

    let icons = Bundle.main.infoDictionary!["CFBundleIcons"] as! [String: Any]
    let primaryIcon = icons["CFBundlePrimaryIcon"] as! [String: Any]
    let iconFiles = primaryIcon["CFBundleIconFiles"] as! [String]
    return UIImage(named: iconFiles[0])!

iconFiles[0] возвращает AppIcon60x60, который использует [email protected] в основном пакете размером 120x120, что намного ниже, чем 1024x1024.

Я провел следующее исследование:

  1. В настройке моего приложения я использую каталог ресурсов (Assets.xcassets -> AppIcon) с файлом изображения icon1024.png размером 1024x1024.

  2. На вкладке General целевой настройки я установил AppIcon в качестве значка приложения.

  3. в полученном продукте (файл .app) я вижу 3 связанных файла:

Затем я использовал приложение «Asset Catelog Tinker» для проверки Assets.car и получил один файл icon1024.png.

Я попробовал собрать как iOS 17, так и iOS 18, и получил одинаковую структуру папок .app.

Это означает, что при сборке с использованием базового SDK iOS 17 при вызове UIImage(named: "AppIcon") каким-то волшебным образом загружается файл Assets.car/icon1024.png. Однако, если я сделаю UIImage(named: "icon1024"), или UIImage(named: "icon1024.png"), или UIImage(named: "Assets.car/icon1024.png") или UIImage(named: "Assets.car/icon1024.png"), он вернет ноль.

Я не знаю, почему я работал раньше (кто-нибудь знает?), но это больше не работает при сборке для iOS 18. Так что мне делать?

Поскольку ios18 все еще находится в стадии бета-тестирования, вам следует оставить отзыв о бета-версии.

Paulw11 01.07.2024 23:52

@Paulw11, есть ли другие способы получить доступ к файлу значка приложения в высоком разрешении?

OMGPOP 01.07.2024 23:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

По общему признанию, это была интересная задача.

Действительно, значки приложений, похоже, упакованы в файл car, и к ним невозможно получить доступ во время выполнения.

Также кажется, что в комплекте есть только несколько отдельно стоящих значков небольшого размера... но

Просматривая параметры компилятора, я нашел этот параметр:

ASSETCATALOG_COMPILER_STANDALONE_ICON_BEHAVIOR

который можно найти в:

Build Settings > Asset Catalog Compiler - Options > Standalone Icon File Behavior

и, похоже, это позволяет реализовать практически то, что мы хотим:

Определяет, создаются ли для основного значка приложения отдельные файлы PNG или ICNS, а также включается содержимое в файл Assets.car. По умолчанию небольшое подмножество размеров включено в виде отдельных файлов, что позволяет внешним инструментам управления отображать репрезентативный значок без чтения файла CAR. Для этого параметра можно установить значение «все» или «нет», чтобы включать значки большего или меньшего размера в виде отдельных файлов.

Итак, после установки этого параметра на all мы счастливы, но имейте в виду, что это работает (я провел все тестирование), только если вы включите хотя бы один вариант, специфичный для схемы (из-за отсутствия лучшего термина).

Например, если вы установите только слот Any Appearance, он не будет содержать копию значка 1024.

Итак, вы хотите что-то вроде этого:

и вот, наконец, мы получаем великолепную иконку 1024, отдельно стоящую в комплекте:

который, конечно, вы можете загрузить либо с помощью существующего кода (поскольку значки теперь включены в CFBundleIcons/CFBundleIconFiles), либо напрямую через UIImage(named: "AppIcon1024x1024"), либо с помощью любого другого связанного с Bundle API.

Да, кстати, есть еще один флаг (Include All App Icon Assets - ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS), который также отображает альтернативные значки (т. е. ресурсы значков, которые не являются основными).

Знаете, почему CFBundleIconName работал в iOS 17? Кажется волшебным, что раньше это работало

OMGPOP 11.07.2024 01:33

Учитывая, что iOS18 все еще находится в стадии бета-тестирования и одной из основных особенностей является то, как система обрабатывает значки приложений, это либо ошибка, либо сознательное решение (возможно, для уменьшения размеров бандлов — можно только догадываться). Хотя я бы определенно открыл для этого радар. Имейте в виду, что API (CFBundleIconName) работает точно так же, как и раньше, теперь компилятор не включает значок найма по умолчанию.

Alladinian 11.07.2024 08:20

Другие вопросы по теме

Похожие вопросы

Как сделать так, чтобы верхняя часть фона списка оставалась фиксированной?
Как создать VStack, содержащий коллекцию текстовых полей при нажатии кнопки в Swift iOS?
Вызов асинхронной функции в .sheet или .fullScreenCover SwiftUI
Ограниченный доступ к фотографиям, дающий полный доступ на iOS при использовании image_picker на Flutter
Как отключить изменение цвета заголовка, когда выделенное состояние для UIButton с помощью UIButtonConfiguration активно?
Шифрование AES/GCM/NoPadding в Swift iOS (минимальное развертывание 12.1) не дает ожидаемой длины зашифрованного текста
Каков результат #if MACRO и MACRO определен без значения?
Приложение React-Native iOS аварийно завершает работу сразу после запуска при создании сборки для разработки
Как заставить Spring Animations с ограничениями вести себя правильно?
Пытаюсь реализовать полосу во Flutter/iOS, и я получаю ошибки во всех сгенерированных файлах в Pod, поэтому я даже не могу запустить приложение