Enregistrement de la logique de filtrage dans Swift Combine. Partie 2

Combiné orienté données





La traduction de l'article a été préparée spécialement pour les étudiants du cours avancé "iOS Developer" .





Dans l' épisode précédent, nous avons réussi à modéliser un flux de valeurs, où un opérateur simple ( delay) était attaché à chaque valeur .

Dans cette partie, nous allons examiner quelques autres opérateurs, les créer Codeableet enfin les convertir en éditeur de combinaison au moment de l'exécution.



Types d'opérateurs


Avant de commencer à les modéliser, nous devons comprendre quels types d'opérateurs existent.

Le site Web ReactiveX les décompose en environ 10 catégories: opérateurs de conversion création, transformation, filtrage, combinaison, gestion des erreurs, auxiliaire, conditionnel, mathématique / agrégé, contre-pression, connectable-observable et observable (To). Si vous êtes intéressé, ReactiveX a une bonne explication pour chaque type et opérateur.
Remarque: Si vous n'êtes pas familier avec RxSwift, Observable dans RxSwift est équivalent à Publisher in Combine.
Dans la partie précédente, nous avons mentionné l'opérateur delay, qui fait référence au utilitytype auxiliaire ( ). Aujourd'hui, nous allons nous concentrer sur la préservation de deux filteringopérateurs de filtrage ( ).



Opérateurs de filtre


Ce type d'opérateur empêche tout ou partie (ou aucun) des éléments de flux de se déplacer plus en amont en fonction de cette condition.

dropFirst


dropFirstarrête la transmission des premiers néléments. Nous pouvons simplement l'ajouter à notre énumération Operator, étant donné sa simplicité.

enum Operator {
 case delay(seconds: Double)
 case dropFirst(count: Int)
}

Nous pouvons également facilement convertir ce cas de référencement en éditeur.

extension Operator {func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> { 
switch self {
   case .dropFirst(let count):
       return publisher.dropFirst(count).eraseToAnyPublisher()
 //   
 }}}

L'opérateur dropFirstpeut maintenant être enregistré et affiché dans la liste des opérateurs.



L'enregistrement dropFirstest similaire à un opérateur delay. Peut-être que le filtrage n'est pas si différent des opérateurs auxiliaires. Eh bien, essayons une autre déclaration avant de tirer une telle conclusion.

Filtre


En revanche dropFirst, qui a des critères de filtrage très simples, l'opérateur filterutilise la fermeture au lieu d'un type primitif. C'est un cas plus compliqué. Comment sauver et propager une fermeture?

filter(_:)

Republie tous les éléments qui correspondent à la fermeture donnée.

developer.apple.com


Examinons de filterplus près la méthode .

func filter(_ isIncluded: @escaping (Self.Output) -> Bool) -> Publishers.Filter<Self>

Sa fermeture isIncludedprend un type universel et renvoie une valeur booléenne.

Y a-t-il quelque chose dans Foundation qui représente des conditions logiques et renvoie une valeur logique? Ça me rappelle quelque chose?

Filtrer avec NSPredicate


La réponse est NSPredicate. Si nous pouvons enregistrer les conditions de filtrage sous forme d'expressions sous forme de chaîne, nous pouvons simplement transmettre la valeur du flux et l'utiliser NSPredicatepour évaluer les résultats.

Continuons et ajoutons filterà la liste.

enum Operator {
 case delay(seconds: Double)
 case dropFirst(count: Int)
 case filter(expression: String)
}

Tout ce que nous devons faire est de filtrer les expressions comme %d !=3ou %@ != “D”; par conséquent, l'expression est un type approprié. De même, nous devrions pouvoir déplacer la fiche filter vers Publisher.

extension Operator {
func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> { 
 switch self {
   case .filter(let expression):
   return publisher.filter { value in
               NSPredicate(format: expression,
                           argumentArray: [value])
                .evaluate(with: nil) }.eraseToAnyPublisher()
      
     //   
 }}}

Comme prévu, nous envoyons l'expression à NSPredicateavec la valeur envoyée par Publisher.

Notez que NSPredicateaccepte un tableau d'arguments. Par conséquent, cela devrait fonctionner avec quelques modifications, même lorsque les valeurs prennent le format de tuples, ce qui est très courant dans les scénarios réactifs. Nous y reviendrons à l'avenir lorsque nous parlerons d'opérateurs combinés.



Comme vous pouvez le voir, Filter Stream est ajouté à ce tableau d'instructions stocké et converti en Publisher pour filtrer le nombre 3 à partir des valeurs supérieures.



Dans le prochain épisode: Enregistrement des opérateurs de transformation, cartographie et numérisation


Dans la démo GIF, vous pouvez constater que la liste des opérateurs est assez vide. Au cours des prochaines semaines, nous allons le remplir de différents types d'opérateurs: les opérateurs de transformation, mapet scan.
Vous pouvez trouver le code source dans ce référentiel combine-magic-swifui dans le dossier combine-aire de jeux.

Nous nous réjouissons de vos commentaires et vous invitons à ouvrir la journée au cours .

All Articles