[SWIFT] Ich möchte Combine auch in UIKit verwenden.

Einführung

Mit der Veröffentlichung von iOS14 wurde Swft selbst aktualisiert und die Swift-Benutzeroberfläche wurde in diesen Tagen standardisiert. Ich denke, es gibt viele Leute, die iOS12 nicht schneiden und Combine in der Praxis nicht verwenden können.

Aber ich würde gerne eine neue Technologie ausprobieren. SwiftUI + Combine ist eine etwas hohe Hürde, aber zunächst möchte ich Combine alleine mit dem bekannten UIKit ausprobieren! !!

Diesmal habe ich also einen Artikel mit folgendem Inhalt geschrieben.

Ich hoffe, Sie finden es nützlich. : Bogen:

Umgebung

Es wurde bestätigt, dass dieser Artikel in den folgenden Betriebsumgebungen funktioniert.

Was ist Kombinieren?

Kurz gesagt, es handelt sich um ein "echtes asynchrones Apple-Framework". Ich werde die Erklärung von Apple Developer zitieren.

The Combine framework provides a declarative Swift API for processing values over time.

Es bedeutet so etwas wie "Das Combine-Framework bietet eine deklarative API für die Verarbeitung von Werten im Laufe der Zeit."

Dies ist die Hauptfunktion von Combine, und es scheint die Natur des asynchronen Frameworks zu sein.

Kennen Sie die Charaktere in Kombinieren

Bevor Sie versuchen, Combine zu verwenden, werde ich den Gesamtablauf und die Zeichen vorstellen, die Sie für die Verwendung von Combine benötigen.

Charakter

In der Abbildung sieht es so aus.

Untitled Diagram.png

In der Rx- und reaktiven Programmierung wird das obige Konzept häufig durch ein Marmordiagramm ausgedrückt. Persönlich ist es einfacher, sich das Konzept in der Abbildung vorzustellen, das die Zeichen in 1-1-1 zeigt, wie in der obigen Abbildung gezeigt.

Lassen Sie es uns vorerst berühren

Nachdem Sie die Charaktere kennen, berühren wir sie vorerst.

Dies ist der Anmeldebildschirm, den Sie häufig sehen. Wenn Sie mit MVVM entwerfen, müssen Sie die von TextField in View empfangene E-Mail-Adresse an ViewModel binden. Nehmen wir die damalige Implementierung als Beispiel, um die Erklärung und das Implementierungsbeispiel für Publisher, Operator und Subscriber zu sehen.

Publisher Erstens ist Publisher. https://developer.apple.com/documentation/combine/publisher

Publisher ist ein großartiger Typ, der Werte veröffentlichen kann, sodass Sie die E-Mail-Adresse veröffentlichen können, die Sie in View erhalten haben.

Erstellen wir zunächst einen Publisher, der einen Wert ausgibt, wenn sich der Text des TextField ändert.

import Combine

final class LoginViewController: UIViewController {

    @IBOutlet weak var mailAddressTextField: UITextField!

    private let viewModel = LoginViewModel()
    private var binding = Set<AnyCancellable>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Wenn textDidChangeNotification benachrichtigt wird`mailAddressTextField`Stellen Sie das Objekt aus.
        NotificationCenter.default
            .publisher(for: UITextField.textDidChangeNotification, object: mailAddressTextField)

    }
}

Vergessen Sie nicht zu importieren. Wenn sich das textField ändert, wird ein Objekt namens "mailAddressTextField" ausgegeben.

Untitled Diagram (1).png

Operator Als nächstes gehen wir zu Operator. Der Operator ist ein großartiger Typ, der Werte konvertieren kann. Sie können also auch das oben vom Publisher veröffentlichte UITextField-Objekt konvertieren. Bei der Bindung an ein ViewModel mit einem TextField-Wert reicht nur eine Zeichenfolge aus, um an das ViewModel übergeben zu werden. Verwenden wir also den Operator, um das UITextField in einen String zu konvertieren.

import Combine

final class LoginViewController: UIViewController {

    @IBOutlet weak var mailAddressTextField: UITextField!

    private let viewModel = LoginViewModel()
    private var binding = Set<AnyCancellable>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default
            .publisher(for: UITextField.textDidChangeNotification, object: mailAddressTextField)
            .compactMap { $0.object as? UITextField } //Wenn Sie UITextField nicht umsetzen können und es gleich Null wird, spielen Sie es ab
            .map { $0.text ?? "" } //Extrahieren Sie Text aus UITextField und konvertieren Sie ihn in String
    }
}

Ich mache das

Untitled Diagram (2).png

Auf diese Weise übernimmt der Operator die Konvertierung und Behandlung des Werts in der Mitte, wenn der von Publisher ausgegebene Wert und der Wert, den Sie erhalten möchten, unterschiedlich sind. Siehe unten für Operatortypen.

Subscriber Der letzte ist Sbscriber. Da Sbscriber ein großartiger Typ ist, der Werte empfangen und verschiedene Dinge tun kann, können Sie die Zeichenfolge der E-Mail-Adresse festlegen, die von Publisher an ViewModel gesendet wird.

import Combine

final class LoginViewController: UIViewController {

    @IBOutlet weak var mailAddressTextField: UITextField!
    
    private let viewModel = LoginViewModel()
    private var binding = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default
            .publisher(for: UITextField.textDidChangeNotification, object: mailAddressTextField)
            .compactMap { $0.object as? UITextField }
            .map { $0.text ?? "" }
            .removeDuplicates() //Beseitigen Sie doppelte Werte
            .eraseToAnyPublisher()
            .receive(on: RunLoop.main)
            .assign(to: \.mailAddress, on: viewModel) //viewModel\.Weisen Sie mailAddress einen Wert zu
            .store(in: &binding)
    }
}

final class LoginViewModel {
    var mailAddress: String = "" {
        didSet {
            print(mailAddress)
        }
    }
}

Es sieht so aus, als ob Sie viel tun, aber es gibt zwei Punkte.

Die Zuweisungsmethode wächst von Publisher und kann einen Abonnenten generieren, während der empfangene Wert an das durch den Schlüsselpfad definierte Objekt übergeben wird. Wenn es jedoch so bleibt, wie es ist, wird der Speicher nicht freigegeben, daher rufen wir ".store (in: & binding)" auf, um die Überwachung abzubrechen.

Untitled Diagram (3).png

Lauf

Wenn Sie mit dem bisherigen Code den Wert von TextField erhalten, wird dieser in ViewModel festgelegt!

Zusammenfassung

Combine ist das echte asynchrone Framework von Apple und verfügt über die folgenden Funktionen.

Kombinieren hat die folgenden Hauptfiguren:

Bonus

Um mich an das Kombinieren zu gewöhnen, erstelle ich auch eine Anwendung, die Bücher verwaltet, indem ich API mit UIKit und Kombinieren drücke. Ich plane, einen API-Client mit Combine und einen Publisher aufzunehmen, der zu einer Erweiterung gemacht wurde, um die Verwendung zu vereinfachen. Schauen Sie also bitte nach, wenn Sie möchten: bow:

kawano108/CombineBookManagerApp

Recommended Posts

Ich möchte Combine auch in UIKit verwenden.
Ich möchte @Autowired in Servlet verwenden
Ich möchte die praktischen Funktionen von Clojure in Kotlin nutzen
Ich möchte auch in Laradock Fischschalen verwenden! !!
Ich möchte ES2015 auch in Java verwenden! → (´ ・ ω ・ `)
Ich möchte ein kleines Symbol in Rails verwenden
Ich möchte DBViewer mit Eclipse 2018-12 verwenden! !!
Ich möchte einige Eigenschaften als JSON-Strings in Jackson erhalten!
[Java Spring MVC] Ich möchte DI in meiner eigenen Klasse verwenden
Ich möchte eine E-Mail in Java senden.
Ich möchte Java8 für jeden mit Index verwenden
Ich möchte APP_HOME an Logback in Gradle übergeben
rsync4j - Ich möchte rsync in Java berühren.
Ich möchte irgendwann sogar in Kotlin sein
Ich möchte den Wert in Ruby erhalten
Ich möchte, dass Sie Scala vorerst als besseres Java verwenden
Ich möchte so etwas wie "cls" in Java machen
Ich möchte NetBeans auf einem Mac verwenden → Ich kann es verwenden!
Ich möchte eine TraceId in das Protokoll einbetten
Ich möchte eine Funktion in der Rails Console definieren
[Android Studio] Ich möchte eine Maven-Bibliothek unter Android verwenden
Ich möchte Schlangenfälle mit Tabellendefinitionen stoppen
Ich möchte in RSpec auf einen GoogleMap-Pin klicken
Ich möchte PowerMock in einer Klasse verwenden, die parametrisierte Tests und gewöhnliche Tests kombiniert
Ich möchte Zeichen konvertieren ...
[Anfänger] Ich möchte die Migrationsdatei ändern.
Ich möchte einen relativen Pfad in einer Situation finden, in der Pfad verwendet wird
Ich möchte mit Ruby (ABC177E) eine schnelle Primfaktorisierung durchführen.
[jackson] Ich möchte die JSON-Werte "0" und "1" als Booleschen Wert erhalten
Ich möchte die Java 8 DateTime-API (jetzt) langsam verwenden.
Ich möchte eine andere Desinfektionsmethode als Ansicht verwenden.
Verwendung von ArgumentMatchern wie Mockitos any () in Kotlin
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben
Ich möchte eine Parkettdatei auch in Ruby erstellen
Ich möchte im gespeicherten Zustand zum selben Bildschirm wechseln
Ich möchte FireBase verwenden, um eine Zeitleiste wie Twitter anzuzeigen
Ich möchte die if-else-Anweisung für bedingte Verzweigungen in Java vereinfachen
Wie man Lombok im Frühling benutzt
Ich möchte Swipeback auf einem Bildschirm verwenden, der XLPagerTabStrip verwendet
Ich habe versucht, Java-Anfänger so einzustellen, dass sie Tastenkombinationen in Eclipse verwenden
Verwendung von InjectorHolder in OpenAM
Ich möchte Geräte in Rails hinzufügen, kann die Installation jedoch nicht bündeln
Wie verwende ich Klassen in Java?
Ich möchte den oberen Rand in der UITableView von Grouped entfernen (schnell)
[Java] Ich möchte mit dem Schlüssel im Objekt eindeutig arbeiten
Ich möchte den Wert von Attribute in Selenium of Ruby ändern
[Android] Ich möchte den Listener über die Schaltfläche in ListView abrufen
[Rails] Ich möchte Daten verschiedener Modelle in einem Formular senden
Ich möchte JSP in Emacs einfacher als die Standardeinstellung schreiben.
Ich möchte im Dialogfeld mehrere Elemente mit einem benutzerdefinierten Layout auswählen