Die drei wichtigsten Neuerungen mit der Einführung von watchOS2

Was also wirklich erwähnenswert ist, wenn Sie auf die watchOS2-Entwicklung umsteigen, sind die folgenden drei Punkte:

  • WKInterfacePicker
  • Komplikationen
  • WCSession

In diesem Artikel werde ich kurz auf jeden von ihnen eingehen.

WKInterfacePicker


WKInterfacePicker ist eine Innovation von Apple, die die Entwicklungsmöglichkeiten zeitweise erweitert. Was ist das Wenn wir Analoga mit der Entwicklung für iOS zeichnen, dann ist dies ein UIPickerView für Uhren, aber mit flexiblerer Funktionalität. Die Verwaltung erfolgt über die Digital Crown (Seitenrad).

Ich werde nicht alle Funktionen erwähnen, sondern nur aufzeigen, was in der Anfangsphase der Entwicklung wichtig sein wird. WKInterfacePicker hat also zwei wichtige Parameter: Style und Focus Style. Durch Ändern des Stils ändern wir die Art und Weise, wie Informationen angezeigt werden.

Ich werde gleich mit einem Beispiel beginnen. Im Gegensatz zu Hipster-Vorstellungen werde ich Code bereitstellen, der in den guten alten Klassikern - Objective-C - geschrieben wurde.

Fügen Sie den Picker-Ausgang zu unserem InterfaceController hinzu:
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfacePicker *picker;

Stellen Sie den Auswahlstil auf den Listenmodus ein.



Und kopieren Sie den Code:

- (void)willActivate {
    // This method is called when watch view controller is about to be visible to user
    [super willActivate];
    NSArray* arrayOfTexts = @[
                              @"Раз",
                              @"Два",
                              @"Три",
                              @"Четыре",
                              @"Пять",
                              @"Шесть",
                              @"Семь",
                              @"Восемь",
                              @"Девять",
                              @"Десять",
                              @"Одиннадцать",
                              @"Двенадцать",
                              @"Тринадцать",
                              @"Четырнадцать",
                              @"Пятнадцать",
                              @"Шестнадцать",
                              @"Семнадцать",
                              @"Восемнадцать",
                              @"Девятнадцать",
                              @"Двадцать"];
    NSMutableArray* arrayOfItems = [NSMutableArray new];
    for (int i = 0; i < arrayOfTexts.count; i++) {
        WKPickerItem *item = [WKPickerItem new];
        [item setTitle: arrayOfTexts[i]];
        [arrayOfItems addObject: item];
    }
    [self.picker setItems:arrayOfItems];
}

Im ersten Fall (Liste) können wir den Text in unserer üblichen Form anzeigen.



Wenn Sie das Element "Stapel" festlegen, erhalten Sie eine Reihe von Bildern mit einer vordefinierten Animation.



Durch Auswahl des Elements Sequenz können wir auch das installierte Bild steuern, jedoch ohne Animation. Auf diese Weise können wir Eigenschaften wie Lautstärke, Empfindlichkeit, Alphakanaltiefe usw. steuern.



Erwähnenswert ist jedoch Folgendes: Bevor Sie mit dem Zeichnen beginnen, sollten Sie ungefähr hundert Storyboards mit einer Auflösung von x2 (x3) erstellen. Dies sorgt für einen reibungslosen Bildlauf und erweitert den Bereich der einstellbaren Werte.

Übrigens können wir den aktuellen Index verfolgen, indem wir eine Aktion erstellen (die Methode entspricht nicht dem Standard, ich persönlich habe eine Delegate-Methode oder so etwas wie die Controller-Interface-Methode für eine Tabelle erwartet table didSelectRowAtIndex).

Wir ziehen den Picker in den Header und schreiben den Namen der Methode wie folgt:

- (IBAction)pickerDidSelectValue:(NSInteger)value;

Als nächstes kontrollieren wir den erhaltenen Wert, wie wir es wünschen.

Durch Ändern des Parameters Fokusstil können wir die Sichtbarkeit der Ränder der Auswahl festlegen oder deaktivieren. Im Moment gibt es jedoch keine Möglichkeit, Fokus-Eigenschaften zu ändern (im aktiven Zustand des Pickers ist der Fokus bei Standardkurven grün).







Generell ist WKinterfacePicker ein leistungsfähiges Tool, das dem Entwickler große Chancen eröffnet.

Komplikationen


Im Kern sind Komplikationen die kleinen Elemente, die wir sehen, wenn wir das modulare Zifferblatt öffnen. Die wörtliche Übersetzung des Wortes Komplikationen ist Komplikationen. Ein Unfall? Ich glaube nicht. Die Shell für eine so scheinbar einfache Funktionalität ist schließlich das gesamte ClockKit-Framework. Wenn Sie sich den Inhalt zum ersten Mal ansehen, können Sie entsetzt sein, obwohl nicht alles so traurig ist. Nehmen wir es so kurz wie möglich, da dieses Thema einen eigenen Artikel wert ist.

Bei der Erstellung eines neuen Projekts wird uns die Möglichkeit geboten, „Komplikationen“ zu verknüpfen. Wenn diese Option aktiviert ist, wird die ComplicationController-Klasse zu unserem Projekt hinzugefügt.



Das CLKComplicationDataSource-Protokoll ist mit dem Header dieser Klasse verbunden. In der Implementierung sind 9 Methoden vordefiniert. Die ersten 4 legen tatsächlich die Bedingungen für die Unterstützung von Komplikationen im Zeitreisemodus fest. Wir interessieren uns für eine andere Methode.

- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
}

Er ist der Schlüssel hier. Darin setzen wir den „Einstiegspunkt“ unserer Komplikation mit den angegebenen Parametern und dem angegebenen Datum. Es sieht so aus: Zuerst erstellen wir ein leeres Objekt der Klasse CLKComplicationTimelineEntry.

CLKComplicationTimelineEntry* entry = nil;

Dann tanzen wir über die Art der Komplikation, die wir verwenden möchten. Nehmen Sie zum Beispiel Modular Small und platzieren Sie dort ein Bild.

    if (complication.family == CLKComplicationFamilyModularSmall) {
        CLKComplicationTemplateModularSmallSimpleImage* image = [[CLKComplicationTemplateModularSmallSimpleImage alloc] init];
        [image setImageProvider: [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"cat"]]]; // не забываем найти png с котейкой :)
        entry = [CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:image];
    }
    handler(entry);

Dann passen wir das ausgewählte modulare Zifferblatt an und erhalten eine lustige Katze aus unserer Testanwendung. Profit







Mit ähnlichen Schemata können Sie Bilder und Texte in verschiedenen Formaten (einzeln, in Blöcken und Spalten) festlegen. Im Allgemeinen ist es sehr praktisch und erleichtert einem Benutzer das Leben, der schnell die neuesten Informationen aus seiner Anwendung herausfinden muss.

WCSession


Eine neue Ära der Synchronisation zwischen iPhone und Apple Watch hat begonnen. Wenn Sie die Zeit von Apples guter „Krücke“ namens openParentApplication gefunden oder die AppGroup zusammen mit dem Wurmloch verwendet haben , ist es Zeit, sie zu vergessen. Jetzt gibt es drei Möglichkeiten, um Informationen mithilfe einer "Sitzung" zwischen Geräten zu übertragen:

  • Anwendungskontext
  • Dateien und Daten übertragen
  • Senden von Nachrichten

Zunächst müssen Sie das WatchConnectivity-Framework verbinden. Es bietet auch die Möglichkeit, zwischen Geräten zu kommunizieren.

  #import 

Verbinden Sie das WCSessionDelegate-Protokoll in den Klassen, zwischen denen wir übertragen werden. Als nächstes überprüfen wir die Sitzungsunterstützung. Wenn alles in Ordnung ist, schalten Sie es ein. In Zukunft führen wir alle Aufrufe der Sitzung über [WCSession defaultSession] durch.

if ([WCSession isSupported]) {
      WCSession *session = [WCSession defaultSession];
      session.delegate = self;
      [session activateSession];
}
NSDictionary *dict = @{@"key": @"То, что мы так хотим передать"};
[[WCSession defaultSession] updateApplicationContext:dict error:nil];
//для получения на обратной стороне используем метод 
-(void)session:(WCSession *)session didReceiveApplicationContext:(NSDictionary *)applicationContext {
  NSString* stringWeNeed =  [applicationContext objectForKey:@"key"];
    NSLog(@"%@", stringWeNeed);
}

Wenn Sie eine ständige Synchronisierung zwischen dem Telefon und der Uhr benötigen, ist dies der beste Weg. Mit der folgenden Option können Sie Informationen mit zwei Methoden übertragen (nacheinander beginnend mit den letzten Änderungen, bevor die Synchronisation zwischen den Geräten

unterbrochen wird) : transferUserInfo: (Senden von NSDictionary)
transferFile: metadata: (Senden einer Datei über URL + NSDictionary mit Metadaten)

Analog:

session didReceiveUserInfo : (get NSDictionary)
session didReceiveFile: (get WCSessionFile mit einem Link zu einer Datei und einer Bibliothek mit Metadaten)

Nun, die letzte Option wird mit einem bestimmten Beispiel betrachtet. Wie bereits erwähnt, importieren wir das WatchConnectivity-Framework in die Standardklassen ViewController und InterfaceController. Wir verbinden das WatchConnectivity-Protokoll:

@interface ViewController : UIViewController 
@interface InterfaceController : WKInterfaceController 

In der Implementierung schreiben wir vor:

- (void)viewDidLoad {
    [super viewDidLoad];
    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}
- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}

Wir zeigen Informationen auf der Uhr an, wenn auf dem iPhone auf eine Schaltfläche geklickt wird. Um dies zu tun, fügen Sie den Knopf und ziehen Main.storyboard IBAction: - (IBAction)buttonClicked:(id)sender;.

Fügen Sie eine Bezeichnung zu Interface.storyboard hinzu und ziehen Sie Outlet:

@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *infoHere;

Durch Klicken auf die Schaltfläche erstellen wir eine Zufallszahl und übergeben sie mit NSDictionary an die Uhr:

- (IBAction)buttonClicked:(id)sender {
   NSString* randomValue = [NSString stringWithFormat:@"%u", (arc4random() % 10000) ]; 
    [[WCSession defaultSession] sendMessage:@{@"key":  randomValue]} replyHandler:^(NSDictionary * _Nonnull replyMessage) {
    } errorHandler:^(NSError * _Nonnull error) {
    }];

Auf der Rückseite schreiben wir vor:

-(void)session:(WCSession *)session didReceiveMessage:(NSDictionary *)message replyHandler:(void (^)(NSDictionary * _Nonnull))replyHandler {
     dispatch_async(dispatch_get_main_queue(), ^{
    NSString* string = [message objectForKey:@"key"];
         [self.label setText:string];
     });
}

Hier gibt es einen wichtigen Punkt. Wir aktualisieren die Benutzeroberfläche im Haupt-Thread asynchron, da es sonst zu Anzeigeproblemen kommt. Um die Gründe zu verstehen, empfehle ich Ihnen, Artikel und Dokumentation zu Multithreading zu lesen.

Um es zusammenzufassen. Ich habe einige Neuerungen aufgelistet, die ich persönlich mit dem Aufkommen von OS2 für am bedeutendsten halte. Zweifellos kann über jeden von ihnen mehr erzählt werden, und zwar ziemlich ausführlich, aber jeder von uns benötigt Grundkenntnisse, um dieses oder jenes Gebiet zu beherrschen. Lassen Sie diesen Artikel zum Dreh- und Angelpunkt für Programmierer werden, die sich für die Entwicklung von watchOS entscheiden.

Jetzt auch beliebt: