easy_dev991 – Telegram
easy_dev991
628 subscribers
37 photos
21 videos
3 files
175 links
Делюсь интересными находками/лайфхаками в процессе разработки под iOS, и возможно ты найдешь что-то полезное для себя!

GitHub: https://github.com/easydev991
Download Telegram
#ios #automation #fastlane

Я уже рассказывал как мне нравится Xcode Cloud для публикации сборок - минимум настроек, все работает хорошо.

Вчера настроил публикацию скриншотов в пет-проекте с использованием fastlane, и выключил воркфлоу в Xcode Cloud, потому что:

⚠️ Он работает медленно - сборка на ноуте (с fastlane) занимает меньше минуты, а в облаке это растягивается на 5 минут
⚠️ Для публикации скриншотов в любом случае нужно или делать ручную работу, или запустить fastlane

Теперь про публикацию скриншотов через fastlane
Для наглядности вот логи:

[18:40:04]: Driving the lane 'ios upload_screenshots' 🚀
...
[18:40:09]: Starting with the upload of screenshots...
[18:40:11]: Deleted 'ru APP_IPAD_PRO_3GEN_129' - (0.814763 secs)
[18:40:11]: Deleted 'en-US APP_IPHONE_67' - (0.814563 secs)
[18:40:11]: Deleted 'ru APP_IPHONE_67' - (0.837923 secs)
[18:40:11]: Deleted 'en-US APP_IPAD_PRO_3GEN_129' - (0.915516 secs)
[18:40:12]: Number of screenshots not deleted: 0
[18:40:12]: Successfully deleted all screenshots
...
[18:40:17]: Uploaded './fastlane/screenshots/ru/iPhone 15 Pro Max-1-[18:40:21]: Uploaded './fastlane/screenshots/ru/iPhone 15 Pro Max-3-sortByDate.png'... (3.672329 secs)
[] Waiting for all the screenshots to finish being processed...
[18:40:28]: Successfully uploaded all screenshots
[] Sorting screenshots uploaded...
[18:40:29]: Successfully uploaded screenshots to App Store Connect


Итого: с момента запуска команды до окончания публикации и сортировки скриншотов прошло 26 секунд - это намного быстрее, чем вручную публиковать скриншоты для двух локализаций на iPad/iPhone, еще и в правильном порядке.
В appstoreconnect для сохранения нужного порядка отображения скриншотов приходится загружать картинки по одной в желаемом порядке🙈

Теперь важные нюансы.

1️⃣ Несмотря на возможность вручную загрузить скриншоты для нужных диагоналей с самых новых девайсов (iPhone 16 Pro Max, iPad M4), fastlane так не может - нужно делать скриншоты на других девайсах, подробнее написал в ридми.
Если попытаться загрузить скриншоты для 16 Pro Max и iPad M4, будут ошибки типа таких:

[16:44:44]: 🚫 Invalid screenshots were detected! Here are the reasons:
[16:44:44]: 🚫 Error: ./fastlane/screenshots/en-US/iPad Pro 13-inch (M4)-1-demoList.png - Invalid screen size (Actual size is 2064x2752. See the specifications to fix https://help.apple.com/app-store-connect/#/devd274dd925)
...
[16:44:44]: 🚫 Error: ./fastlane/screenshots/ru/iPhone 16 Pro Max-3-sortByDate.png - Invalid screen size (Actual size is 1320x2868. See the specifications to fix https://help.apple.com/app-store-connect/#/devd274dd925)

Да, я прочитал документ по ссылке из логов с ошибкой, и я нашел там iPhone 16 Pro Max + iPad Pro (M4), но fastlane не может их опубликовать 🤔

2️⃣ Если ваш аккаунт связан с несколькими командами разработки, то при настройке fastlane нужно явно указать идентификатор команды в поле itc_team_id, пример есть в Appfile - даже если вы не знаете идентификатор, то при первом запуске команды для публикации скриншотов fastlane сам предложит выбрать команду, там и можно скопировать идентификатор и поставить в Appfile.

3️⃣ По умолчанию fastlane делает много всего в команде upload_to_app_store, и лучше сразу выключить лишнее, например, публикацию бинарного файла приложения, запуск precheck перед отправкой и т.д., более подробно про все эти настройки можно почитать в официальной документации к fastlane.

4️⃣ Лучше сразу настроить overwrite_screenshots на true, чтобы после загрузки новых скриншотов не приходилось вручную удалять старые.

Готовый fastfile можно посмотреть в гитхабе.
🔥3
#ios #swift #swiftui #contest

Нужно сверстать стек, где есть несколько Text с одинаковой структурой:


private struct UserInfo: Identifiable {
let id = UUID()
let label: String
let value: String
}


Должно получиться примерно как на картинке.

Шрифт для label: .system(size: 20, weight: .bold)
Шрифт для value: .system(size: 16, weight: .regular)

Не используем markdown в тексте.

Вот готовые модели для превью:


let items: [UserInfo] = [
.init(label: "Почта", value: "test@example.com"),
.init(label: "Телефон", value: "+79123456789"),
.init(
label: "Адрес",
value: "117513, г. Москва, ул. Профсоюзная, д. 129, корп. 3, кв. 117, подъезд 5, этаж 8"
)
]


Кто первый сделает, тот молодец 🚀
👌3
#ios #swift #swiftui #hint

На днях добавлял SwiftUI-вьюху внутрь UIKit-ячейки для экрана с коллекцией.
Вьюха просто принимает на вход данные и показывает что-то внутри себя.

⚠️Но есть нюанс: на iOS < 16 нельзя просто так добавить SwiftUI-вьюху в ячейку - для этого нужно делать костыль с хостингом и т.д.

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

На этом экране еще и кнопка есть для скролла к той самой ячейке - и при первом скролле к ней она выглядит плохо.

Решается эта проблема очень просто - можно добавить вьюхе два состояния: "загрузка" и "готово".
В "загрузке" показываем любой принятый в проекте индикатор загрузки или скелетон, а в "готово" - обычное состояние вьюхи.
Ну и в саму вьюху внутрь onAppear добавляем смену состояний.

Теперь при первом рендере этой ячейки появится индикатор загрузки, а потом сразу корректное состояние.
2🔥1
#ios #swift #swiftui #contest

Субботний челлендж по знанию SwiftUI 🤓

Во вложении два варианта анимации разворачивания и сворачивания секции.

Нужно реализовать целевое поведение.
Задача очень простая, если знать как делать 😁

Код для старта тут.

Кто первый, тот молодец 🚀
👀3👍2
#ios #appstore #appstoreconnect

Опубликовал приложение с площадками для воркаута под своим аккаунтом, т.к. отключили Xcode Cloud для РФ и я не мог больше обновлять приложение на аккаунте владельца сайта workout.su.

Перед публикацией предполагал, что могут возникнуть сложности, т.к. вряд ли одобрят два приложения с почти одинаковым названием и полностью одинаковым дизайном.

Решил попробовать сначала отправить приложение на проверку, и не удалять старое приложение.

В результате получил временный бан от эпол в appstoreconnect, и они запросили мои документы (уже в третий раз за год).
Отправил им документы, бан сняли, как и в прошлые разы.

При этом завернули новое приложение по причине Spam 😁
Там перечисляли, что у меня и дизайн копирует существующее приложение, и код, и вообще полный дубликат.

Спросил их, можно ли опубликовать новое приложение после удаления старого - сказали можно.

Согласовал с владельцем сайта удаление старого приложения, удалил его, и теперь могу обновлять приложение уже в своем аккаунте в максимально удобном формате (через fastlane).
4🔥2
easy_dev991
Рассказал про 5 способов, от нерабочих до рабочих, почитать можно в платном канале: - базовая подписка - продвинутая подписка - сеньорская подписка
Сегодня был в центре города и решил на личном опыте узнать как сбербанк устанавливает свое банковское приложение на айфоны своих лояльных пользователей.

1. Взял талончик и ждал в очереди 11 минут (хотя по ощущениям прошла вечность)
2. Меня пригласили для установки приложения, но сделать этого не смогли 🙈

Полную версию можно прочитать в платном канале:
- базовая подписка
- продвинутая подписка
- сеньорская подписка
😁11👀1
#ios #swift #swiftui #contest

Описание задачи и код для старта есть в гитхабе.
Кто первый, тот молодец! 🚀
1
#ios #swift #swiftui #uikit

Все еще верстаете на ките и пользуетесь таблицами/коллекциями для создания списков? При этом хочется использовать в этих экранах SwiftUI?
Не беда! В iOS 16 добавили нативную интеграцию SUI в ячейках с помощью contentConfiguration.

Вот так нужно было в apple презентовать этот инструмент😁, а не тихонечко сказать в одном из видео, что вот теперь вы можете в ячейках добавлять SUI.

Алгоритм работы с этой штукой:

1️⃣ Верстаем вьюху для ячейки на SUI
2️⃣ В самой ячейке делаем проверку на iOS 16, и если версия подходит, то добавляем вьюху как показано в документации, можно обращаться напрямую к свойству contentConfiguration внутри ячейки
3️⃣ Если версия iOS < 16, то либо не показываем обновленный UI (😁), либо используем костыли с UIHostingController

Важный момент: если просто добавить SUI-вьюху в ячейку и не настроить отступы для конфигурации, то будут добавлены дефолтные отступы по горизонтали и вертикали.
Чтобы такой фигни не было, нужно вручную поверх конфигурации добавить отступы через метод margins.

Пример настройки contentConfiguration с нужными отступами:

func setup(with viewModel: DemoCollectionCellViewModel) {
if #available(iOS 16.0, *) {
contentConfiguration = UIHostingConfiguration {
SwiftUIView(viewModel: viewModel)
}.margins(.horizontal, 12) // <- вот тут задали отступы по горизонтали
} else {
setupOld(with: viewModel)
}
}


Весь код для демо-ячейки можно посмотреть в гитхабе.
3🔥2
#ios #career

Хабр добавил тесты для подтверждения навыков в резюме, получилось забавно 😁

Более подробно расскажу в платном канале✔️
🔥5
#ios #swift #swiftui #swiftdata #cloudkit #hint

Создали новое iOS-приложение с использованием Swift Data и CloudKit, но оно крашится после добавления контейнера?

Не беда!
На скриншоте исправление краша в только что созданном приложении, где включена галка Host in CloudKit и добавлен ваш CloudKit Container.

Все поля в моделях Swift Data должны быть или опциональными, или иметь дефолтное значение.

Если оставить поле timestamp без дефолтного значения, будет краш:

Thread 1: Fatal error: Could not create ModelContainer: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer, _explanation: nil).

При этом краша не будет, если снять галку с контейнера в настройках проекта 😐

Будет здорово, если в новом Xcode появятся более прозрачные ошибки на этот случай (бету не ставил).
🔥8
#ios #xcode

Приятная новость в Xcode 26 RC (ссылка), краткий перевод ниже.

Xcode получил новую функцию кеширования компиляции, которую можно включить вручную и которая ускоряет циклы сборки и тестирования для Swift и C‑подобных языков.
Эта фича сохраняет результаты компиляции для набора исходных файлов и при повторной компиляции тех же файлов использует их из кеша, сокращая время сборки.
Наибольшую выгоду это дает при переключении между ветками или выполнении чистых сборок.


На мой взгляд это здорово, скоро проверим на практике 👍
10