WCSession mit mehr als einem ViewController verwenden

8

Ich habe viele Fragen und viele Antworten gefunden, aber kein letztes Beispiel für die Anfrage:

Kann jemand ein abschließendes Beispiel in Objective C geben? Was ist Best Practice, um WCSession mit einer IOS-App und einer Watch-App (WatchOS2) mit mehr als einem ViewController zu verwenden.

Was mir bisher aufgefallen ist, sind folgende Fakten:

1.) Aktivieren Sie die WCSession in der übergeordneten App (IOS) im AppDelegate:

%Vor%

2.) Verwenden Sie auf der WatchOS2-Seite <WCSessionDelegate> . Aber der Rest ist völlig unklar für mich! Einige Antworten sprechen von der Angabe von Schlüsseln im übergebenden Wörterbuch wie:

%Vor%

Andere sprechen über das Abrufen der Standardsitzung

%Vor%

Andere reden über verschiedene Warteschlangen? "Es liegt in der Verantwortung des Kunden, bei Bedarf in eine andere Warteschlange zu wechseln. Senden Sie die Nachricht an die Hauptstelle zurück."

Ich bin total verwirrt. Bitte geben Sie ein Beispiel, wie WCSession mit einer IOS App und einer WatchOS2 App mit mehr als einem ViewController verwendet wird.

Ich brauche es für den folgenden Fall (vereinfacht): In meiner Eltern-App messen ich Herzfrequenz, Trainingszeit und Kalorien. Bei der Watch App 1. ViewController zeige ich die Herzfrequenz und die Trainingszeit am 2. ViewController an. Ich zeige auch die Herzfrequenz und die verbrannten Kalorien.

    
Ron Wood 14.09.2015, 22:32
quelle

4 Antworten

9

Soweit ich die Aufgabe verstehe, brauchen Sie nur Synchronisation in Phone -> Watch Richtung, also kurz gesagt eine Minimalkonfiguration für Sie:

Telefon:

Ich glaube, der application:didFinishLaunchingWithOptions: -Handler ist der beste Ort für die WCSession -Initialisierung, daher sollte der folgende Code dort stehen:

%Vor%

Dann irgendwo in Ihrem Code, der zum Beispiel eine Herzfrequenz misst:

%Vor%

Aktualisierung:

Beobachten:

ExtensionDelegate.h:

%Vor%

ErweiterungDelegate.m:

%Vor%

Irgendwo in Ihrem Controller, nennen wir es XYZController1.

XYZController1:

%Vor%

Der Code wurde nicht getestet. Ich habe ihn einfach geschrieben, so dass es Tippfehler geben kann.

Ich denke, die Hauptidee ist jetzt ziemlich klar und eine Übertragung von verbleibenden Datentypen ist keine so schwierige Aufgabe.

Meine aktuelle WatchConnectivity-Architektur ist viel komplizierter, basiert aber dennoch auf dieser Logik.

Wenn Sie noch Fragen haben, können wir eine weitere Diskussion in den Chat verschieben.

    
Dmytro Hutsuliak 15.09.2015, 19:49
quelle
4

Nun, das ist eine vereinfachte Version meiner Lösung, wie von Greg Robertson gefordert. Sorry, es ist nicht mehr in Objective-C; Ich kopiere nur aus einem bestehenden AppStore-genehmigten Projekt, um sicherzustellen, dass es keine Fehler gibt.

Im Prinzip kann jedes WatchDataProviderDelegate an die Datenprovider-Klasse angehängt werden, da diese den Array-Inhaber für Delegaten bereitstellt (anstelle einer schwachen var). Eingehende WCSessionData werden mit der Methode notifyDelegates () an alle Delegierten weitergeleitet.

%Vor%     
igraczech 25.02.2016 09:06
quelle
3

Die Session-Verwaltung (WCSession ist Singleton) in einem View-Controller riecht aber nach MVC-Verstoß (und ich habe schon zu viele Blogeinträge auf diese Weise gesehen).

Ich habe eine Regenschirm-Singleton-Klasse über die WCSession erstellt, die zuerst von Watch Extension Delegate stark referenziert wird, um sicherzustellen, dass sie bald geladen wird und nicht während der Arbeit freigegeben wird (zB wenn ein View-Controller während der Übertragung von UserInfo oder verschwindet) transferCurrentComplicationUserInfo passiert in einem anderen Überwachungsthread).

Nur diese Klasse handhabt / hält die WCSession und entkoppelt die Sitzungsdaten (Model) von allen View-Controllern in der Watch-App. Dabei werden die Daten hauptsächlich durch statische statische Klassenvariablen angezeigt, die mindestens grundlegende Thread-Sicherheit bieten .

Dann wird diese Klasse sowohl vom Komplikations-Controller als auch vom Blick-Controller und anderen View-Controllern verwendet. Updates laufen im Hintergrund (oder in backgroundFetchHandler), keine der Apps (iOS / WatchOS) muss überhaupt im Vordergrund sein (wie im Falle von updateApplicationContext) und die Sitzung muss nicht unbedingt aktuell erreichbar sein.

>

Ich sage nicht, dass dies die ideale Lösung ist, aber schließlich hat es angefangen, wenn ich es so gemacht habe. Ich würde gerne hören, dass das völlig falsch ist, aber da ich viele Probleme hatte, bevor ich mit diesem Ansatz fortfuhr, bleibe ich jetzt dabei.

Ich gebe das Codebeispiel nicht absichtlich an, da es ziemlich lang ist und ich nicht möchte, dass irgendjemand es blind kopiert und einfügt.

    
igraczech 15.09.2015 20:18
quelle
0

Ich habe mit "try and error" eine Lösung gefunden. Es funktioniert, aber ich weiß nicht genau warum! Wenn ich eine Anfrage von der Watch an die IOS-App sende, erhält der Delegierte dieses ViewControllers der Watch-App alle Daten aus der Hauptwarteschlange von der IOS-App. Ich habe den folgenden Code in - (void)awakeWithContext:(id)context und - (void)willActivate aller ViewControllers der Watch App hinzugefügt:

Beispiel 0 ViewController:

[self packageAndSendMessage: @ {@ "Anfrage": @ "Ja", @ "Zähler": [NSString stringWithFormat: @ "% i", 0 ]}];

Beispiel 1 ViewController1:

[self packageAndSendMessage: @ {@ "Anfrage": @ "Ja", @ "Zähler": [NSString stringWithFormat: @ "% i", 1 ]}];

%Vor%     
Ron Wood 15.09.2015 19:37
quelle

Tags und Links