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

GitHub: https://github.com/easydev991
Download Telegram
Некоторые вещи на отдельную статью не тянут, поэтому буду их публиковать не по графику.

#git #terminal #hint
Удаляем все локальные ветки
(кроме dev, develop, master, main)

1) Переходим в терминале в папку с проектом
2) Проверяем, чтобы в команде были указаны ветки, которые нельзя удалять (по аналогии с dev, develop, master и main)
3) Запускаем команду


cd myProject
git branch | grep -v "dev" | grep -v "develop" | grep -v "master" | grep -v "main" | xargs git branch -D
👍21
#terminal #simulator #hint

Очистить симуляторы

Иногда бывает нужно сделать очистку, чтобы избавиться от нерабочих симуляторов.
Такое может происходить при обновлении версии Xcode или Mac OS.
Если не очистить симуляторы, то могут вылезать непонятные ошибки типа "Не удалось запустить симулятор" без понятных причин, а при создании нового симулятора старый никуда не денется и будет занимать место.

Что делаем:

1. Закрываем симуляторы и Xcode (прямо через command + Q)
2. Выполняем команды в терминале:

xcrun simctl shutdown all && xcrun simctl erase all
xcrun simctl --set previews delete all
🔥2
#hint #json

Тут рассказал, как проще всего делать модели для парсинга JSON.
Мне повезло - я узнал об этом способе еще когда был джуном 🙃
🔥72
#terminal #xcode #fix #simulator #hint

Запускаю симулятор в Xcode и вижу такую ошибку, хотя вчера все отлично работало 🤦‍♂️

Мне помогла команда в терминале:


sudo killall -9 com.apple.CoreSimulator.CoreSimulatorServicesudo killall -9 com.apple.CoreSimulator.CoreSimulatorService
5🔥2🤣2
#hint #swiftpackage

Вдруг кто-то не знал: с версии Swift 5.9 можно использовать модификатор уровня доступа package внутри пакетов (Swift Package), чтобы доступ к чему нужно был из любого места в рамках одного пакета (ссылка на внедренный proposal).

Например, если в пакете несколько "продуктов" (products), то каждый из них может обращаться к штукам другого с уровнем доступа package.
🔥2
#hint #xcode

Как запустить Xcode 15* на MacOs 15*?

Очень просто: правый клик на иконке приложения в "программах" -> показать содержимое пакета -> переходим в папку Contents/MacOs -> дважды кликаем по скрипту Xcode
4
#hint #xcode

Очищаем память на маке от мусора Xcode и не только

Эта статья может пригодиться, если после удаления DerivedData на маке все еще мало свободного места. И даже после удаления Xcode/AndroidStudio могут сохраниться старые данные - будем их удалять.

Я за полчаса удалил почти 200 гб 🤯

Почитать можно в платном канале:
- базовая подписка
- продвинутая подписка
- сеньорская подписка
🔥31
#git #terminal #hint #gitignore

Бывает, в гит запушили файл, которого там не должно быть, а потом добавили его в .gitignore. Но файл уже находится в гите, и его нужно оттуда удалить.

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


git rm -rf --cached .
git add .


Пояснение:
- первая команда говорит гиту перестать отслеживать все файлы в проекте, но не удалять их с диска
- вторая команда снова добавляет все файлы и изменения в список для включения в следующий коммит, но теперь уже с учётом .gitignore (то есть файлы, которые вы исключили, не попадут в список)
- остается только сделать коммит/пуш с изменениями 👌

Для экспертов по гиту:
Знаю, что можно проделать операции только с нужным файлом, а не со всеми сразу, но мне удобнее так, и вдруг кому-то тоже 😉
5🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
#terminal #simulator #hint

По умолчанию нажатия на экране iOS-симулятора не отображаются, но это легко поправить командой в терминале:

defaults write com.apple.iphonesimulator ShowSingleTouches 1

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

Важный нюанс: если включить запись экрана симулятора через кнопку Record Screen в самом симуляторе, то в получившейся записи не будут видны эти нажатия.

Нажатия будет видно только при записи экрана самого мака (видео можно обрезать, чтобы было похоже на запись через Record Screen)
🔥72🤔1
#terminal #git #hint

Бывает, что после выполнения задачи ветку удаляют в репозитории, а локально она все еще висит. И когда таких веток набирается много, можно в них запутаться 😅

Чтобы удалить разом все такие ветки, нужно перейти в терминале в папку с проектом и выполнить команду:

git branch | grep -v "^\*" | while read branch; do
if ! git show-ref --verify --quiet refs/remotes/origin/$branch; then
git branch -D $branch
fi
done


Объяснение:
git branch выводит список всех локальных веток.
grep -v "^\*" исключает текущую активную ветку (чтобы не удалять её).
• Для каждой ветки проверяется, существует ли она на сервере (refs/remotes/origin/branch).
• Если ветка отсутствует на сервере, она удаляется принудительно (git branch -D), что удалит ветку даже если в ней есть несмерженные изменения.

Перед выполнением команды нужно убедиться, что вы переключились на ветку, которую не хотите удалять (например, main или master).
👌51
#terminal #bundler #rbenv #hint

Кто читал предыдущую статью про использование Makefile, и при этом впервые применил эти команды, скорее всего после перезапуска терминала столкнулся с ошибкой типа такой:

Could not find ‘bundler’ (2.6.5) required by your Gemfile.lock. (Gem::GemNotFoundException)


И после перезапуска терминала не работают команды bundle*, например: 

bundle exec fastlane


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

Вот что нужно сделать, чтобы эти настройки не сбрасывались.

1. Выполните в терминале по очереди эти две команды:

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc


2. Затем примените изменения командой:

source ~/.zshrc


3. Всё! Теперь rbenv всегда будет работать автоматически, когда вы открываете терминал в папке проекта с файлом .ruby-version.

Это безопасно:
- rbenv специально разработан так, чтобы работать для каждого проекта отдельно, если в проекте есть файл .ruby-version
- Добавление строк в ~/.zshrc просто включает автоматическое переключение версий Ruby для каждого проекта, но не фиксирует какую-то одну версию Ruby глобально
- Все ваши проекты будут использовать именно ту версию Ruby, которая указана в их собственном .ruby-version.

Если захотите убрать эти настройки, просто откройте файл ~/.zshrc (например, командой nano ~/.zshrc или через Finder) и удалите строки:

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init - zsh)"


После этого сохраните файл и выполните:

source ~/.zshrc


Всё вернётся как было 👌
👌21
easy_dev991
Нужно переименовать сразу несколько файлов, а еще - изменить габариты сразу нескольких картинок (ширину/высоту). Сможешь сделать это без единой строчки кода на маке (и без терминала)?
This media is not supported in your browser
VIEW IN TELEGRAM
#finder #macos #hint

Как изменить габариты сразу нескольких картинок (ширину/высоту) на MacOS:
1. Выделяем нужные картинки
2. Открываем с помощью "Просмотр"
3. Выделяем все (command + A)
4. Инструменты -> Настроить размер
👍5🔥2😁1
easy_dev991
struct ComplexModel { let name: String let id: Int let price: Double let isActive: Bool let creationDate: Date let websiteURL: URL? let tags: [String] let statistics: [String: Int] let description: String? } /// Выполнить…
#swift #foundation #keypath #hint

Представляю вам KeyPathComparator, доступный с iOS 15.
Решает задачу из опроса на изи)


struct ComplexModel {
let name: String
let id: Int
let price: Double
let isActive: Bool
let creationDate: Date
let websiteURL: URL?
let tags: [String]
let statistics: [String: Int]
let description: String?
}

/// Выполнить работу с массивом и вернуть отсортированный массив
func doWork(with items: [ComplexModel]) -> [ComplexModel] {
// другая логика ...
return items.sorted(using: KeyPathComparator(\.name)) // <- вот
}

/// Выполнить работу с массивом и вернуть отсортированный массив
/// - Parameters:
/// - items: Изначальный массив
/// - order: Порядок сортировки
/// - Returns: Отсортированный массив
func doSortedWork(with items: [ComplexModel], order: SortOrder) -> [ComplexModel] {
// другая логика ...
return items.sorted(using: KeyPathComparator(\.name, order: order))
}
👍4🔥2
#ios #swift #swiftui #maps #geocoding #hint

На прошлой неделе заметил, что релиз 3.10 приложения с площадками стал сильно греть телефон, и даже в статистике аккумулятора спустя всего 10 минут использования мое приложение было первым в списке по потреблению энергии 🙈

В том релизе я сделал много классных штук, и в том числе немного обновил старый код для работы с картой, в результате нагрузка на девайс выросла в разы.

На днях выпустил релиз с исправлением этих проблем, и вот главные выводы:

1️⃣ Если нужно получить локацию пользователя с использованием CLLocationManager, то лучше не использовать startUpdatingLocation(), а просто вызывать requestLocation() по таймеру, например раз в 10 секунд - нагрузка ощутимо упадет

2️⃣ Использовать reverseGeocodeLocation нужно не чаще раза в минуту, а лучше еще реже - если координаты ощутимо изменились (на 50 метров, например), и это точно нужно для правильной работы фичи

3️⃣ Если используете MKMapView внутри SwiftUI-обертки, то напишите явную проверку в методе updateUIView, чтобы обновление карты выполнялось только тогда, когда это 100% нужно - я для этого сделал флаг shouldUpdateRegion и передаю его в карту, а в методе updateUIView вызываю замыкание при обновлении карты, чтобы снять флаг
🔥52
#ios #uitest #xctest #bug #hint

Любопытный момент: оба скриншота сделаны при запуске одного и того же UI-теста, но внимательный глаз заметит разницу - слева у приложения accentColor синий, т.е. дефолтный, а справа - черный (такой и должен быть).

Не заметил, в какой момент тесты сломались и перестали уважать настройку accentColor в assets, но вот фикс этой проблемы:


WindowGroup {
RootScreen()
.tint(.accent) // <- исправляет accentColor в тестах
}


Еще раз повторю, что в обычном режиме работы приложение корректно распознает accentColor, и только в режиме UI-тестов нужен фикс.
4👍2
#ios #swift #swiftui #hint

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

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

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

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

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

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