#ios #swift #macos
#iOS #swift #macos
Вопрос:
У меня есть приложение, которое во многом одинаково для обеих платформ, разделяя логику и имена объектов. Но код поневоле отличается, и я хотел бы объединить его.
Я пытаюсь максимально консолидировать логику, чтобы упростить обслуживание. Однако на iOS я использую
result.text = valueString
а в macOS это
result.stringValue = valueString
Могу ли я каким-либо образом сделать то, что я хочу: поделиться всем в своем коде, кроме определений пользовательского интерфейса? Я посмотрел на Chameleon, но, похоже, он не простирается так далеко.
Ответ №1:
Я бы создал протокол, которому соответствуют оба класса, который действует как средство доступа к тексту:
protocol TextAccess {
func getText() -> String?
}
extension UITextView: TextAccess {
func getText() -> String? {
return text
}
}
extension NSTextField: TextAccess {
func getText() -> String? {
return stringValue
}
}
Таким образом, вы просто вызываете .getText()
любой из типов для вызова их конкретного средства доступа. Возможно, вам потребуется обернуть приведенный выше код в #if
блоки, но это всего лишь примерный пример одного из способов решения этой проблемы.
Другим подходом было бы создание псевдонима:
#if os(iOS)
typealias TextField = UITextField
#endif
#if os(macOS)
typealias TextField = NSTextField
#endif
В любом месте, к которому вы обращаетесь TextField
, вы будете получать доступ к классу, зависящему от платформы.
Ответ №2:
Я нашел это. На самом деле очевидно, если вы знаете, какой конкретный синтаксис…
#if os(iOS)
result.text = valueString
#else
result.stringValue = valueString
#endif
Комментарии:
1. Интересно, но какой тип
result
должен быть для компиляции? Я не понимаю, как это вам помогает; это просто отодвигает проблему дальше (на само объявлениеresult
). В конечном итоге это ничего не «консолидирует».2. Так что я заметил. Теория была хорошей, но это означает, что я могу скопировать и вставить всю функцию целиком с блоками #if в ней между обеими версиями приложения. Я точно знаю, как это сделать в Cobol!