Найти из какого пакета функция была вызвана автоматически - PullRequest
0 голосов
/ 12 июля 2019

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

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

Синтаксис выглядит следующим образом

public extension UIImageView {
    convenience init(_ key: UIImage.Key) {
        self.init(image: UIImage(named: theme.imageName(for: key)))
    }
}

let imageView = UIImageView(.detailDisclosure)

и его дочерняя функция

let image = UIImage(.detailDisclosure)

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

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

convenience init(_ key: UIImage.Key, in locality: AnyClass? = nil) {
    self.init(image: UIImageView.localImage(named: key.rawValue, in: locality))
}

// Currently assumes this method and default assets are in the main bundle by default 
fileprivate static func localImage(named name: String, in locality: AnyClass?) -> UIImage? {
    let bundle = (locality != nil) ? Bundle(for: locality!) : Bundle.main
    return UIImage(named: name, in: bundle, compatibleWith: nil)
}

let image = UIImage(.detailDisclosure, in: ThisProjectTheme.self)

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

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

Что было бы лучше, если бы потребитель этого API не указал другое locality, мы находим его местонахождениедля них автоматически;вместо текущего решения перейти в основной комплект.

В будущем большинство этих запросов будут поступать от проектов, имеющих собственные активы.

Я видел, например, file: String = #file

convenience init(_ key: UIImage.Key, file: String = #file, in locality: AnyClass? = nil)

Значит, мы можем, очевидно, взломать его, но мне интересно, есть ли элегантное решение для получения отправителя или, если на то пошло, без того, чтобы потребитель неявно отправлял его функции?

Спасибо за ваше время

1 Ответ

1 голос
/ 12 июля 2019

"из какого пакета была вызвана функция автоматически"

Как бы это ни звучало привлекательно, вы по-настоящему этого не хотите.В тот момент, когда вы обнаружите, что копирование / вставка некоторого кода из одного проекта в другой заставляет его вести себя по-разному, это момент, когда вы потеряете свои шарики.

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

import UIKit

class ImageProvider {
    let bundle: Bundle

    init(bundle: Bundle) {
        self.bundle = bundle
    }

    init(forMainClass mainClass: AnyClass) {
        self.init(bundle: Bundle(for: mainClass)!)
    }

    func image(
        named: String,
        with configuration: UIImage.Configuration? = nil
    ) -> UIImage {
        return UIImage(named: name, in: self.bundle, with: configuration)?
    }
}

Каждое приложение создаст свой собственный ImageProvider, который ищет ресурсы в своем собственном пакете.

Это имеет несколько ключевых преимуществ:

  1. Интерфейс может быть легко извлечен в протокол, и может быть создана фиктивная реализация для использования в тестах.
  2. У вас есть единственная точка входа в систему изображений,который позволяет вам обрабатывать кэширование, создание тем, определение размера и т. д.
  3. Вы можете расширить это для обработки поиска по нескольким пакетам («сначала найдите мой пакет приложений, если нет, попробуйте пакет этой инфраструктуры»)
  4. Вы можете расширить это, чтобы использовать перечисление для идентификации изображений, а не необработанные строки.
...