J'ai le protocole suivant :

public protocol ImagesContainer {
    associatedtype ImageName: RawRepresentable where ImageName.RawValue == String
    static var bundle: Bundle? { get }
}

Avec une implémentation comme celle-ci

struct ImagesMain: ImagesContainer {
    public static var bundle: Bundle? { return .main }
    public enum ImageName: String {
        case loading, success, error
        case profile, address
    }
}

struct ImagesUser: ImagesContainer {
    public static var bundle: Bundle? { return .main }
    public enum ImageName: String {
        case profile, address, country
    }
}

Donc généralement je l'ai utilisé dans les structures de modèle

struct ViewModel {
    let icon: ImagesMain.ImageName
}

Ce qui est bien pour un ImagesContainer. Mais j'ai un tel conteneur pour chaque bundle et j'aimerais les mélanger et les assortir lors de la création de ces ViewModels. Pour l'instant, ils sont toujours liés à un ImagesContainer. Je voudrais généraliser cela, afin que je puisse spécifier n'importe quel nom d'image à partir de n'importe quel ImagesContainer.

Quelque chose comme

struct ViewModel {
    let profileIcon<T: ImagesContainer>: (T, T.ImageName)
    let addressIcon<T: ImagesContainer>: (T, T.ImageName)

}

Je ne peux pas le mettre sur la structure elle-même, car il peut y avoir plusieurs propriétés avec différents ImagesContainer et ainsi de suite. Existe-t-il un moyen d'avoir un générique autonome?

1
warly 7 févr. 2020 à 14:29

1 réponse

Meilleure réponse

Pour tous ceux qui sont intéressés par une solution, voici ce que j'ai trouvé.

public protocol ImageAsset {
    func image() -> UIImage
}

private struct DefaultImageAsset<T: ImageAssetsContainer>: ImageAsset {
    let container: T.Type
    let imageName: T.ImageName

    init(_ container: T.Type, _ imageName: T.ImageName) {
        self.container = container
        self.imageName = imageName
    }

    func image() -> UIImage {
        return container.image(imageName)
    }
}

Donc la logique réelle est à l'intérieur de la structure et le type n'est pas communiqué à l'extérieur :

struct ViewModel {
    let profileIcon: ImageAsset
    let addressIcon: ImageAsset
}

let viewModel = ViewModel(
     profilesIcon: DefaultImageAsset(ImagesMain.self, .profile),
     addressIcon: DefaultImageAsset(ImagesUser.self, .address)
)

viewModel.profilesIcon.image()
0
warly 19 mars 2020 à 16:44