Совместное использование кода между iOS и macOS — NSTextField и UITextField

#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!