Евгений @Streetmage
iOS Developer
Information
- Rating
- Does not participate
- Location
- Таганрог, Ростовская обл., Россия
- Date of birth
- Registered
- Activity
Specialization
Mobile Application Developer
Lead
From 350,000 ₽
iOS development
SWIFT
Client-server applications
В том и дело, что порядка нет. То есть при изменении Info.plist методом + writePropertyList:toStream:format:options:error: сам файл будет полностью меняться. И получится, что каждый раз при сохранении ключи перемешиваются.
В рамках доменов и данного примера решение то, что надо, с хранением всего в Info.plist. Но если будет просто массив строк, то всё равно придется хранить отдельный json файл.
Тут дополню, а разве при использовании метода
+ writePropertyList:toStream:format:options:error:
у нас порядок элементов не изменится в Info.plist, так как корневой элемент это Dictionary? Тогда, возможно, что регулярка будет всё же лучше.
Например, вот так:
И нужно было оставить всё, что без value_without_filter_tag. А все другие значение с подстрокой "with_filter_tag" заменить.
Пример здесь абстрактный и больше был призван показать сам процесс возможности использования утилиты на Swift-е. Он упрощен специально, чтобы не вносить доп. условий.
В исходной задаче файл json привести сразу к формату plist-а было невозможно, это был сторонний сервис. Плюс был нюанс с тем, что не все поля нужно заменять в массиве, а только те, у которых в названии есть определенный признак, то есть ещё дополнительно предварительно отфильтровать.
На этом этапе я решил, что использование консольных утилит типа PlistBuddy потребует их более глубокого изучения и встанет вопрос поддержки другими iOS разработчиками. Например, выше вроде бы простое решение с утилитами plutil и PlistBuddy всё равно требует знания нюансов и опыта работы с этими утилитами.
А вот ваше решение с тем, чтобы хранить дополнительную инфу сразу в plist и не хранить отдельно JSON интересное. Хотя для нас бы не сработало, потому что массив состоял из строк, а не из словарей, куда можно ещё дополнительно закинуть тот же description.
Возможность использовать
UserDefaults
, как я понял, не указана явно в публичной документации. Но способ получше парсинга.Переменные окружения проекта будут доступны, если запустить скрипт из Build Phases секции проекта. А если потребуется запустить скрипт уже из другого места, придется их самом прописывать? Тогда уже лучше выглядит передача параметров.
Спасибо за совет! Это будет получше регулярок.
Про ArgumentParser я упомянул в статье, что если менеджер зависимостей не SPM и подключать его не хочется, то можно воспользоваться уже доступными способами.
1. Чтобы создать свой валидатор наследник от VLDRegExpValidator необходимо переопределить статический метод + (NSString *)regExpPattern. Как правило полей с разным количеством символов может быть много, поэтому создавать класс наследник под каждый случай не является хорошей идеей. Аналогичная ситуация и с валидацией числа. Допустим есть три отдельных поля с днем-месяцем-годом, то с текущей архитектурой создавать придется 3 класса наследника от VLDRegExpValidator, которые будут содержать лимиты чисел для дня-месяца-года.
Тут сразу напрашивается вопрос о том, почему была выбрана именно такая архитектура, с переопределением статического метода. Почему нельзя было просто создать свойство, которое бы могло принять строку-паттерн? Есть случаи, когда разработчик называет объект, в нашем случае валидатор, одним именем с одним паттерном, а потом меняет регулярное выражение и начинает использовать валидатор в других целях. В данном случае такую неоднозначность было решено устранить описанным способом. Наиболее часто встречаемые ситуации, для проверки которых, как правило, используется регулярное выражение, были реализованы в классах потомках VLDRegExpValidator
2. Первая причина, почему наследование было выбрано как инструмент расширения функциональности текстовых полей ввода, это удобство для разработчика в плане подключения фреймворка. То есть все сводится к замене названия класса и делегата и объявления правил проверки.
Второй целью является интеграция созданных валидаторов с полями ввода.
Третьей целью создания кастомных полей было ограничение вводимых символов. Как правило, если такое ограничение вводится на проекте согласно ТЗ, то разработчик реализует метод делегата — (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string. Чтобы избежать избыточного кода в контроллерах было решено перенести логику в класс наследник от текстового поля.
Четвертой целью для использования наследования является то, что делегаты UITextFieldDelegate и UITextViewDelegate срабатывают только на действия пользователя. Но есть случаи, когда используется форма с автозаполнением полей. Таким образом в поле нельзя присвоить программно больше символов, чем разрешено.