2 votes

Comment utiliser conditionnellement Combine @Published lorsque la cible de déploiement minimum est définie sur iOS 12.2 ?

J'ai une application avec un objectif de déploiement minimum de iOS 12.0 . Il y a des parties écrites en SwiftUI y Combine . Toutes les méthodes et tous les types utilisant les deux bibliothèques sont marqués par le symbole @available(iOS 13.0, *) . L'application fonctionne dans cette configuration mixte depuis janvier sans aucun problème.

Pour profiter de la stabilité de l'ABI et réduire la taille de l'application, je veux définir la nouvelle cible de déploiement minimum à iOS 12.2 .

Lorsque je fais cela, l'application se bloque au lancement (simulateur iOS 12.4) avec l'affichage suivant dans la console :

dyld : lazy symbol binding failed : impossible de résoudre le symbole _$s7Combine9PublishedVMa dans /Users/YYYYYYY/Library/Developer/CoreSimulator/Devices/UUD-UUD-UUD-UUD/data/Containers/Bundle/Application/UUD/XXXXXXX.app/XXXXXXX car la dylib dépendante n°29 n'a pas pu être chargée dyld : can't resolve symbole _$s7Combine9PublishedVMa sur /Users/YYYYYYY/Library/Developer/CoreSimulator/Devices/UUD-UUD-UUD-UUD/data/Containers/Bundle/Application/UUD-UUD-UUD/XXXXXXXapp/XXXXXXX car la dylib dépendante n°29 n'a pas pu être chargée

L'application se bloque également lorsqu'on tente de la lancer sur un iPhone fonctionnant sous iOS 12.4.

Si je supprime tous les @Published du code mais laisser tous les autres Combine y SwiftUI Les bits liés à l'application peuvent être utilisés sur iOS 12.

Même si toutes les classes contenant @Published sont marqués par @available(iOS 13.0, *) J'ai essayé de les envelopper dans des #. if canImport(Combine) ou en appliquant #if canImport(Combine) à chaque @Published variable. Cela ne sert à rien.

Je sais que je pourrais changer

@Published var name = ""

à

var name = "" {
    willSet {
        objectWillChange.send()
    }
}

Mais cela semble être une mauvaise solution de contournement.

Comment puis-je augmenter la cible de déploiement à iOS 12.2 et continuer à utiliser @Published lorsque le dispositif est en marche iOS 13.0 ou plus ?

2voto

Dávid Pásztor Points 21448

Vous devez lier faiblement le Combine (et SwiftUI si vous l'utilisez également) à votre projet. Vous pouvez y parvenir en utilisant l'option OTHER_LDFLAGS construire le cadre.

OTHER_LDFLAGS = -weak_framework Combine -weak_framework SwiftUI

Vous n'avez pas vraiment besoin canImport vous n'avez besoin que d'un cadre faiblement lié. Bien entendu, vous avez toujours besoin de l'option @available sur tous les types qui utilisent Combine .

1voto

mluisbrown Points 2455

Vous ne pouvez pas utiliser l'enveloppe de propriété @Published dans un objectif de déploiement inférieur à iOS 13. La seule façon de le faire est celle que vous avez décrite ci-dessus.

Dans votre classe (qui doit être conforme à la norme ObservableObject ), au lieu de :

@Published var name = ""

Vous devez avoir :

var name = "" {
    willSet {
        if #available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) {
            self.objectWillChange.send()
        }
    }
}

Il se peut que vous deviez également ajouter explicitement l'option objectWillChange dans votre classe :

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public lazy var objectWillChange = ObservableObjectPublisher()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X