Hilfreiche Ratschläge

TamTam Messenger - ein Ersatz für Telegramm?

Pin
Send
Share
Send
Send


Hallo habr Mein Name ist Yuri Buyanov, ich bin der Entwickler des TamTam Messenger. Heute möchte ich Ihnen ein wenig darüber erzählen, wie es geschaffen wurde und wie es von innen aufgebaut ist. TamTam ist ein neuer Messenger der Mail.Ru Group, der auf Basis der Anwendung OK Messages entwickelt wurde. 2016 haben wir in Odnoklassniki einen separaten Messenger für diejenigen erstellt, die häufig in sozialen Netzwerken korrespondieren und dies lieber mit einer separaten Anwendung tun.

Das Experiment erwies sich als erfolgreich und so beschlossen wir zu Beginn des Jahres, OK Messages als separaten Messenger aus dem sozialen Netzwerk unter unserer eigenen Marke TamTam zu entwickeln, jedoch mit einem rekrutierten Startpublikum. Bereits in den ersten Wochen nach dem Start erschienen Zehntausende von Kanälen in TamTam und das Publikum kommunizierte weiterhin so aktiv wie in OK Messages. Dies wurde dank der schnellen Arbeit der Anwendung und einiger technischer Merkmale ermöglicht. Ich werde Ihnen mehr über sie erzählen.

Schwierigkeiten, die mit Ideen kamen

Beginnen wir mit den Schwierigkeiten: Sie brachten uns die Ideen, die später in das Produkt implementiert und schließlich in die Vorteile der Anwendung umgesetzt wurden. Es geht in erster Linie um die schnelle und stabile Arbeit des Boten.

Das Startpublikum von TamTam ist aus der ganzen Welt, auch mit einer unregelmäßigen Abdeckung des Mobilfunknetzes (und manchmal mit einem völligen Mangel an festem Internet). In einigen GUS-Ländern außerhalb von Großstädten ist eine 2G-Verbindung im Allgemeinen das einzige Internetfenster.

Es war auch wichtig, dass nicht alle potenziellen TamTam-Benutzer jedes Jahr ein neues iPhone oder einen neuen HOT NOVEL von Samsung kaufen. Laut Statistik ist das beliebteste Gerät für iOS unter unseren Benutzern das iPhone 5s und für Android die kostengünstige Version Galaxy 2014-2015. Gleichzeitig hat TamTam ein relativ junges Publikum: 28% des täglichen Publikums sind Menschen im Alter von 27 bis 34 Jahren, und mehr als die Hälfte der Benutzer (54%) sind unter 35 Jahre alt.

Daher war es für uns von Anfang an ein vorrangiges Anliegen, die Anwendung dahingehend zu optimieren, wie leistung, so und Netzwerkarbeit. Kurz gesagt, es war für Benutzer nicht wahrnehmbar, dass die Anwendung auf einer beliebigen Verbindungsebene funktioniert. Und mit jedem Publikumswachstum auch. TamTam zeigt in den ersten Monaten gute Zahlen: Die Anzahl der Installationen nähert sich bereits 3 Millionen, und die Anzahl der Kanäle beträgt bereits mehr als 50.000.

Wie wir die Bewerbung schnell gemacht haben

Leistung aus Sicht des Benutzers ist in erster Linie die Startgeschwindigkeit. Die Zeit, die vergeht, bevor der neue Inhalt angezeigt wird (z. B. beim Öffnen eines Chats mit einer neuen Nachricht per Push-Benachrichtigung). Die Glätte der Arbeit als Ganzes - insbesondere der Schriftrolle. Im iOS-Team versuchen wir, die Leistung auf dem iPhone 5 und dem iPhone 4S zu testen und zu messen. Das Android-Team verfügt über das Galaxy S3 und Megafon Login für 1000 Rubel. Infolgedessen fliegt die Anwendung nur auf leistungsstärkeren Geräten.

In jeder Testassembly können Sie den Frame-Zähler pro Sekunde aktivieren, und die Dauer von Operationen in Engpässen wird in den Protokollen und im Statistiksystem aufgezeichnet.

Diese Grafik zeigt beispielsweise die Zeit vom Start der Anwendung beim Öffnen durch Drücken bis zu dem Moment, an dem der Benutzer diese bestimmte Meldung auf dem Bildschirm sieht. Zwei Tropfen in der Grafik entsprechen der Einbeziehung von Inhalten, die von der Hälfte und von allen Benutzern gepusht werden.

Trotz der Fülle an Tools und Metriken bleiben subjektive Gefühle das Hauptinstrument zur Bewertung der Anwendungsleistung. Niemand kann genau sagen, welche Verzögerung in Millisekunden beim Öffnen des Nachrichtenbildschirms akzeptabel ist, aber fast jeder kann feststellen, ob er das Gefühl hat, dass die Anwendung "dumm" ist.

Wie optimieren wir? Zunächst entfernen wir alles Mögliche aus dem Hauptstream: Arbeiten mit der Datenbank (mehr dazu weiter unten), Arbeiten mit dem Netzwerk, Serialisieren und Deserialisieren von Daten, Verarbeiten von Bildern und sogar Berechnen im Zusammenhang mit dem Satz.

Wenn wir die Anwendung starten oder den Chat-Bildschirm öffnen, werden wir durch umfangreiche Vorgänge im Hintergrund nicht vor einer sichtbaren Verzögerung bewahrt. Daher müssen einige Vorgänge wie das Setzen von Texten noch rechtzeitig optimiert werden, während andere am besten sofort nach Erhalt der Nachricht ausgeführt und das Ergebnis ihrer Ausführung in der Datenbank zwischengespeichert werden.

Bei der Auswahl von Lösungen und Bibliotheken von Drittanbietern in Engpässen haben wir auch versucht, Geschwindigkeit und Kompaktheit zu berücksichtigen. Genau aus diesem Grund haben wir MessagePack ausgewählt (und für iOS speziell einen Benchmark für verschiedene Implementierungen erstellt), die Bibliothek für die Zuordnung von Daten zu Objekten von Mantle zu YYModel geändert und uns für lz4 als Algorithmus für die Datenverkehrskomprimierung entschieden.

Auch zu erreichen reibungsloser Betrieb der Schnittstelle Wir optimieren das Rendering symptomatisch:

  • Vermeiden Sie Offscreen-Rendering, bei dem der Prozessor geladen wird.
  • Ändern Sie im Hintergrund die Bildgröße, anstatt den Standard-UIViewContentMode zu verwenden, der im Hauptstream ausgeführt wird.
  • unsere UI-Hierarchien „flacher“ und einfacher machen,
  • Wir zwischenspeichern die Objekte und Daten, deren Erstellung zu teuer ist. Beginnend mit der Höhe der Zellen mit Text und endend mit YYTextLayout (ein Objekt, das Informationen zur Anzeige von Text in der YYText-Bibliothek speichert), NSAttributedStrings und sogar den UIViews selbst.

In allen Listen gibt es ein manuelles Layout ohne automatisches Layout. Wir lieben Auto-Layout zwar auch sehr und verwenden deklarative Layouts mit Masonry im Code - aber nur dort, wo es angebracht ist.

Offline und arbeiten mit schlechtem Internet

Bei mit dem Netzwerk arbeiten Wir versuchen, Datenverkehr und Verzögerungen zu minimieren, indem wir ein schnelles, kompaktes Protokoll und aggressives Caching wählen.

Um mit dem Server zu kommunizieren, verwenden wir nur TCP-Sockets und ein Binärprotokoll. Dies ermöglicht es uns, sowohl Aktualisierungen vom Server in Echtzeit zu erhalten als auch im vertrauten "Anforderungs-Antwort" -Modus zu arbeiten.

Die API selbst, d. H. Ein Satz von Befehlen über einem Protokoll auf niedriger Ebene, kann in Zukunft über einem anderen Transport implementiert werden, z. B. über Web-Sockets. Bei alledem müssen wir die übergeordnete Logik der Anwendung nicht berühren.

Die Pakete selbst bestehen aus einem Header fester Länge mit Dienstinformationen: Befehlscode, Protokollversion, Nutzdatenlänge. Antworten auf Anforderungen können in einer anderen Reihenfolge und gemischt mit Serverbefehlen eingehen. Daher enthält der Header eine Folgenummer, mit der Sie die Anforderung und die Antwort verknüpfen können.

Als Nutzdatenformat haben wir uns für messagepack entschieden. Es erfordert keine schwere Aufgabe der Schaltung, ist sehr kompakt und verfügt über ziemlich raffinierte Serialisierungsbibliotheken für viele Plattformen. Tatsächlich ist es ein effektives binäres Analogon von JSON. Um den Verkehrsverbrauch weiter zu reduzieren, komprimieren wir die Nutzlast mit dem lz4-Algorithmus. Wir haben es auch wegen seiner Geschwindigkeit und geringen Belastung der CPU und des Akkus ausgewählt.

Eine der wichtigsten Möglichkeiten, um den normalen Betrieb der Anwendung in einem fehlerhaften Netzwerk sicherzustellen, ist maximale Offline-Unterstützung. Eine Anwendung sollte maximale Daten zwischenspeichern, weniger Zeit und Verkehr für die Synchronisierung aufwenden und in der Lage sein, das Senden von Befehlen zu verzögern, bis eine Verbindung angezeigt wird. Darüber hinaus kann die Verbindung auch beim nächsten Start der Anwendung wieder hergestellt werden, dh, alle anstehenden Aufgaben zum Senden sollten in der Datenbank gespeichert werden können.

Nach der Verbindung authentifiziert sich der Client und fordert gleichzeitig wichtige Daten an: Einstellungen, eine Liste der Kontakte und Chats mit den neuesten Nachrichten. Wir speichern den Zeitstempel des letzten Updates (im Zeitrahmen des Servers) und übergeben ihn an die Anforderung, nur das zurückzugewinnen, was sich wirklich geändert hat. Nachdem die Verbindung hergestellt wurde, können wir Aktualisierungen in Echtzeit erhalten, z. B. neue Nachrichten oder Änderungen an den Kontaktdaten.

Der Chatverlauf ist etwas komplizierter. Das Hochladen des gesamten Verlaufs aller Chats im Voraus ist sinnlos, aber wir haben einmal das Problem, dass wir zwischengespeichert werden und versuchen, nicht mehr zu fragen. Wenn Sie sich ansehen, welche Abschnitte des Chat-Verlaufs zwischengespeichert sind, werden wir feststellen, dass der Verlauf „Lücken“ aufweist. Beispielsweise haben wir beim Aktualisieren der Chat-Liste nach dem Anmelden festgestellt, dass sich die letzte Nachricht im Chat geändert hat. Gleichzeitig haben wir in der Datenbank einen Abschnitt (oder mehrere Abschnitte) des Chat-Verlaufs, der während der vorherigen Sitzung zwischengespeichert wurde. Außerdem wissen wir nicht, wie viele Nachrichten sich zwischen der letzten Chat-Nachricht und der vorherigen zwischengespeicherten Nachricht auf dem Server befinden, was die Komplexität erhöht.

Daher speichern wir zusätzlich zu den Nachrichten selbst Metadaten über fortlaufende Teile der Geschichte - die Blöcke, die wir zwischengespeichert haben. Beim Scrollen im Chat verwenden wir diese Informationen: Sie helfen uns zu bestimmen, ob die nächste Seite aus der Datenbank geladen oder eine Anfrage an den Server gesendet werden soll. Oder vielleicht beides. Wenn neue Abschnitte des Verlaufs vom Server empfangen werden, ändern sich diese Abschnitte in der Größe und verschmelzen miteinander (wenn der Client versteht, dass der gerade empfangene Abschnitt des Verlaufs zwei unterschiedliche Abschnitte verbindet, die in der Datenbank verfügbar sind).

Da viele Vorgänge offline ausgeführt werden können, haben wir einen Mechanismus zum Speichern von Aufgaben entwickelt. Er kann Aufgaben ausführen, auf deren Abschluss warten, ihren Status in der Datenbank speichern oder sie laden und ausführen, wenn die Anwendung gestartet wird.

Aufgaben können in der Datenbank gespeichert werden, sie kapseln die gesamte Ausführungslogik. Da Abhängigkeiten von anderen Aufgaben und vom Status der Anwendung sehr komplex sein können, wird deren Verfolgung auch in den Aufgaben selbst implementiert. Beispielsweise sollte die Aufgabe des Sendens einer Nachricht mit einem Foto sicherstellen, dass das Foto verarbeitet wurde, auf ein CDN hochgeladen wurde (hierfür sind separate Aufgaben verantwortlich), (falls erforderlich) auf eine Netzwerkverbindung warten und erst dann direkt versuchen, die Nachricht selbst zu senden.

Zwei Tricks für einen reibungslosen Applikationsbetrieb

Ich werde ein wenig über ein paar Tricks sprechen, mit denen wir die Einschränkungen des Systems umgangen haben, die uns daran hindern, eine benutzerfreundliche und reibungslose Benutzeroberfläche zu erstellen. Am Beispiel einer iOS-Anwendung.

Eine der Schwierigkeiten bei der Entwicklung war das endlose Scrollen im Chat, d. H. Laden des Nachrichtenverlaufs, der für den Benutzer unsichtbar ist, wenn der Chat nach oben gescrollt wird. In 99% der Fälle befindet sich der Benutzer genau am unteren Rand des Chats und möchte nach oben scrollen, um alte Nachrichten zu lesen. Hier stehen wir vor zwei Problemen.

Erstens ist es ärgerlich, ständig an den Anfang der Nachrichtenliste zu stoßen und alle paar Bildschirme auf Downloads zu warten. Dieses Problem war nicht sehr schwer zu lösen: Wir haben nicht gewartet, bis der Benutzer ganz nach oben gescrollt und die "Wendung" dort gesehen hat, sondern haben versucht, die vorherigen Seiten der Story bereits während des Scrollens anzufordern: sowohl vom lokalen Cache als auch vom Server. Wenn sich Nachrichten im Cache oder bei einer schnellen Verbindung befinden, hat der Benutzer einfach keine Zeit, nach oben zu scrollen, bis wir ein neues Nachrichtenpaket anzeigen können.

Das zweite Problem stellte sich als weitaus schwerwiegender heraus: Nach dem Einfügen einer solchen Seite am Anfang der Nachrichtenliste (erstellt auf der Basis von UITableView) wird das contentOffset für den bereits geladenen Abschnitt verschoben und der Bildlauf „springt“. Natürlich können wir die Größe der eingefügten Seite berechnen und den contentOffset zurücksetzen, aber dies führt zu einem scharfen Stopp der Bildlaufanimation, was hässlich ist und den Benutzer entmutigt. Wir haben auf verschiedene Arten versucht, dies zu tun, zum Beispiel indem wir contentSize-Tabellen über KVO nachverfolgten, sind jedoch immer gescheitert: Die UITableView ist einfach chronisch nicht in der Lage, Elemente an den Anfang der Liste zu setzen.

Infolgedessen konnten wir nach einer Reihe von Versuchen dieses Problem durch eine Art „Hack“ lösen: Wir stellen die Liste mit .transform auf den Kopf und drehen dann jede Zelle in die entgegengesetzte Richtung. Der Benutzer bemerkt nichts, aber jetzt wird das contentOffset von unten gezählt, und das Laden alter Nachrichten hat keinerlei Auswirkungen auf ihn.

Diese Lösung hat eine Reihe von Fallstricken, aber wir haben es auch geschafft, sie zu umgehen, und sie stören uns nicht. Zunächst müssen Sie die invertierten Zellenindizes in die Indizes in Ihrem Datenmodell konvertieren und umgekehrt. Wenn Sie mehr als einen Abschnitt haben, sind die Berechnungen sehr kompliziert, daher ist es besser, sich auf einen zu beschränken. Dies erlaubt uns natürlich nicht, Floating-Section-Header zu verwenden, die auf dem Chat-Bildschirm nützlich wären, um beispielsweise Trennzeichen nach Tag im Verlauf anzuzeigen. Letztendlich stellte sich jedoch heraus, dass schwimmende Separatoren nicht so schwierig manuell auszuführen sind.

Zweitens kann es in seltenen Fällen schwierig sein, die Koordinaten in den Zellen zu berechnen, wenn Sie beispielsweise mit Gesten arbeiten. Sie können jedoch auch alle gelöst werden. Drittens tritt beim Herunterladen von Daten wieder ein Problem auf, das Laden beim Scrollen ist jedoch sehr selten, sodass es für uns keine große Schwierigkeit darstellt. In diesem Fall wird beim Scrollen nicht vorgeladen, sondern es wird gewartet, bis der Benutzer ganz unten in der Tabelle gescrollt hat. Anschließend wird der Ladeanzeiger angezeigt, die Tabelle aktualisiert und das contentOffset geändert.

Die zweite Schwierigkeit, auf die wir gestoßen sind, sind animierte und asynchrone Listenaktualisierungen. Wenn mehrere unabhängige Aktualisierungen fast gleichzeitig durchgeführt werden (z. B. wird die Verlaufsseite oben im Chat geladen und unten eine neue Nachricht angezeigt), können sich die vom tableView-Delegaten verwendeten Daten ändern, auch wenn die Animation der vorherigen Aktualisierung nicht beendet wurde.

Dies kann dazu führen, dass UITableView die falsche Zelle rendert oder ganz abstürzt. Dies ist sogar noch wahrscheinlicher, wenn Sie den vorherigen Hack verwenden. Sie können natürlich auf die reloadData-Methode verweisen, die in UITableView synchron ist, aber dies führt dazu, dass der Benutzer blinkt, das Scrollen stoppt und andere Dinge stört.

Speziell für solche Fälle haben wir eine separate Warteschlange für die sequentielle Verarbeitung solcher Aktualisierungen eingerichtet. Alle Modelländerungen und deren Zuordnung auf der Benutzeroberfläche werden in den in der Warteschlange befindlichen Blöcken vorgenommen. In diesem Fall kann der Block die Warteschlange zu Beginn der Animation oder einer anderen asynchronen Operation sperren und am Ende entsperren. Daher werden alle Arbeiten mit der Tabelle nacheinander ausgeführt, und die Daten ändern sich erst, wenn die vorherige Animation abgeschlossen ist.

Ausdauer

Um Daten im iOS-Client zwischenzuspeichern, verwenden wir die YapDatabase-Bibliothek.

YapDatabase ist ein Key-Value-Repository auf SQLite mit einer Vielzahl von Funktionen. Diese Bibliothek erscheint mir viel einfacher und flexibler als CoreData. Hier können Sie den Mechanismus für die Serialisierung von Objekten in der Datenbank auswählen: Standardmäßig ist dies NSCoding, und wir verwenden dasselbe MessagePack.

YapDatabase erfordert keine Vererbung von Objekten von der Basisklasse oder implementiert ein Protokoll und bindet keine Objekte an den Kontext. Das Lesen und Schreiben erfolgt über synchrone oder asynchrone Transaktionen.

Und mit Hilfe des Erweiterungssystems stehen dieselben Funktionen wie in der „echten“ Datenbank zur Verfügung: beliebige SQL-Abfragen und Indizierung mehrerer Felder, Volltextsuche, Abonnement für Änderungen (wie in NSFetchedResultsController), Verschlüsselung, Arbeiten mit CloudKit usw. Hallo Welt, ich werde hier keine Beispiele für die Arbeit mit der Datenbank nennen, sie befinden sich im Wiki auf Github.

Nach meinem Geschmack verbessert YapDatabase die Produktivität und Verständlichkeit des Codes, aber einige meiner Kollegen mögen es nicht wirklich. Und sie können verstanden werden: Nachdem Sie lange mit CoreData gearbeitet haben, müssen Sie das Gehirn ein wenig drehen, um zu YapDatabase zu wechseln.

Wenn Sie über mehrere Verbindungen asynchron mit der Datenbank arbeiten, müssen Sie außerdem wissen, wie die Datenbank parallele Lese- und Schreibanforderungen verarbeitet: über eine oder mehrere Verbindungen. Denken Sie auch daran, dass die Objekte in der gesamten Datenbank aktualisiert werden. Sie können nicht nur die Instanz speichern, die Sie vor einiger Zeit gelesen und geändert haben. Sie müssen das Objekt aus der Datenbank lesen, nach Bedarf ändern und es in einer einzigen Transaktion zurückschreiben. Andernfalls können Sie versehentlich veraltete Daten in die Datenbank schreiben.

Im Allgemeinen ist das Arbeiten mit der Datenbank sehr bequem in unseren reaktiven Code-Schreibstil integriert. Asynchrone Transaktionsvorlagen (Lesen / Schreiben / Ändern eines einzelnen Objekts) lassen sich sehr einfach in ReactiveCocoa-Signale einbinden und integrieren die Arbeit mit der Datenbank in einer Kette, indem Netzwerkanforderungen gesendet und verarbeitet werden.

Anwendungsarchitektur

Ich werde nicht viel über Architektur reden, aber erlaube mir nicht, die Gesetze des Genres nicht zu erwähnen. Es gibt bereits viele Berichte und Artikel über MVVM (zum Beispiel das klassische Tutorial in der Version für Objective-C b RAC: Teil 1, Teil 2 oder ein Artikel über die Implementierung dieses Musters für Swift).

Unter der ViewModels-Ebene gibt es eine Reihe von Diensten, die Geschäftslogik, Protokolllogik und Caching implementieren (und wenn möglich kapseln). Die Navigation in der Anwendung wird unter Verwendung des sogenannten Routers ausgeführt, d. H. Eines Objekts, das den zum Öffnen eines Bildschirms erforderlichen Code einkapselt. In der Tat gab es mehrere Router in dem Prozess, da der Router die Tendenz hat, so ein sehr dickes Gott-Objekt zu werden. Deshalb versuchen wir, wo immer möglich, es zu zersetzen. Beispielsweise ist ein separater Router für den gesamten Prozess der Benutzerregistrierung / -authentifizierung verantwortlich.

Aus den Erfahrungen früherer Projekte ist bekannt, dass Dependency Injection die Struktur der Anwendung erheblich vereinfacht und Änderungen in der Architektur erheblich erleichtert. В самом начале мы использовали для DI фреймворк Typhoon, но в ходе оптимизации времени запуска приложения выяснили, что разрешение зависимостей занимает непозволительно долгое время на старте приложения (единицы секунд на слабых устройствах). Поэтому мы перешли на ручной DI через property-based injection. Не сказал бы, что кода стало больше: уровень сервисов в приложении обычно настраивается в одном классе, а вся конфигурация сервисов легко читается. Для share и imessage экстеншенов, естественно, сервисы конфигурируются отдельно, поскольку в этом случае нужен гораздо меньший их набор.

Daher war die Kohärenz des Codes anfangs nicht sehr groß, und selbst nach relativ langer Zeit nach Beginn der Entwicklung konnten wir einige der Dienste und den Serving-Code problemlos in eine separate Bibliothek (genauer gesagt sogar eine Reihe von Bibliotheken) übertragen, die den größten Teil der internen Logik des Messenger implementiert. einschließlich Protokollverarbeitung und Zwischenspeicherung, die in andere Anwendungen eingebettet werden können.

Fazit

Anwendungsleistung oder Offline-Arbeit - für uns ist dies kein Trend, sondern eine echte Möglichkeit, bestimmten Benutzern eine bequeme Kommunikationsmöglichkeit zu bieten. Diejenigen, die teuren mobilen Verkehr oder nur schlechtes Internet haben. Und das ist eine ziemlich ernsthafte Motivation, sich gut zu machen. Infolgedessen müssen die Benutzer eine Bewertung vornehmen. Ich empfehle Ihnen daher, einen Messenger zu installieren und Ihr Feedback in den Kommentaren mitzuteilen. Gerne beantworte ich Ihre Fragen.

Nachrichten und Anrufe

Standardmäßig bietet TamTam die Möglichkeit, in Textform zu kommunizieren. Die Funktionalität der Anwendung in dieser Hinsicht unterscheidet sich praktisch nicht von Telegramm und in der Tat auch nicht von anderen Sofortnachrichten. Wenn Konkurrenten jedoch versuchen, mit Aufklebern Geld zu verdienen, wird eine große Anzahl von ihnen völlig kostenlos zur Verfügung gestellt. Es ist zu beachten, dass fast alle Aufkleber animiert sind. Es gibt nur wenige Originalbilder - im Grunde handelt es sich um Aufnahmen aus Serien, Filmen und Zeichentrickserien. Es sind jedoch diese Aufkleber, die bei jungen Menschen am meisten gefragt sind.

Sie können an TamTam nicht nur eine Textnachricht, sondern auch eine Sprachnachricht senden, wie sie beispielsweise in Vkontakte implementiert ist. Klicken Sie dazu im Texteingabefeld auf das Mikrofonsymbol. Dann können Sie dem Gesprächspartner alle möglichen Dinge mitteilen. Danach müssen Sie nur noch auf die Schaltfläche „Stopp“ klicken und das Gesagte senden.

Hier verfügbar und Anhänge senden. Es können nicht nur Fotos, sondern auch Videos sowie einige völlig andere Dateien sein - beispielsweise Dokumente oder Musik. Wenn Sie der Anwendung Zugriff auf die "Galerie" gewähren, werden die Bilder mit wenigen Klicks im wahrsten Sinne des Wortes gesendet. Standardmäßig werden vom Gesprächspartner stammende Fotos automatisch in den Speicher des Smartphones geladen. Sie können Startbilder auch in der "Galerie" aktivieren. Oder Sie können es in den Einstellungen deaktivieren, wenn der Speicher des Geräts sehr begrenzt ist.

In dieser Hinsicht ähnelt das Programm WhatsApp. Hier sind nicht nur Sprachanrufe verfügbar, sondern auch Videoanrufe. Kurz gesagt, TamTam ist eine weitere Möglichkeit, Mobilfunkbetreibern Schaden zuzufügen, indem sie ihre Dienste teilweise ablehnen.

Vielleicht ist das Hauptunterscheidungsmerkmal von TamTam die Fähigkeit, einen Kanal zu pflegen. Dies kann mit den Gruppen in Vkontakte verglichen werden, in denen verschiedene Informationen veröffentlicht werden. Natürlich ist die Liste der derzeit in TamTam verfügbaren Kanäle noch klein. Sie können jedoch bereits Kanäle finden, die sich mit Spielen, Filmen, Musik und sogar einigen Arten des Sammelns befassen. Es scheint, dass viele Leute, wenn Telegramm blockiert ist, einfach zu TamTam gehen, anstatt ein VPN zu verwenden.

Man könnte meinen, dass dieser Messenger im Wesentlichen die Funktionalität des Konkurrenten von Pavel Durov in Bezug auf die Kanäle vollständig wiederholt. In Wirklichkeit ist dies jedoch nicht der Fall. Um sich in Telegram mit einem bestimmten Kanal vertraut zu machen, müssen Sie entweder dessen genauen Namen kennen oder auf den Einladungslink klicken. In TamTam können Sie einfach einen Teil des Sendernamens in die Suche einbeziehen, woraufhin die Anwendung viele Optionen anzeigt. Wenn Sie beispielsweise das Wort "Play" eingeben, ist der der PlayStation zugewiesene Kanal unbedingt im SERP vorhanden.

Der Inhalt der verschiedenen Kanäle ist unterschiedlich. Jemand veröffentlicht Nachrichten, jemand - humorvolle Bilder und jemand - macht Benutzer mit irgendwelchen Informationen bekannt. Leider ist TamTam bisher nicht sehr beliebt, so dass es keinen Sinn macht, eindeutige Inhalte zu veröffentlichen. Grundsätzlich werden die Aufzeichnungen von anderen Boten und sozialen Netzwerken kopiert.

Wenn Sie in den Einstellungsbereich gehen, sehen Sie in der oberen rechten Ecke die vertikalen Auslassungspunkte. Klicken Sie auf, um das Kontextmenü aufzurufen. So können Sie den Namen und das Foto ändern sowie zu den speziellen Profileinstellungen wechseln. Im entsprechenden Bereich können Sie jedoch nur über sich selbst schreiben und einen Link zu einem Profil erstellen, das für die Veröffentlichung in sozialen Netzwerken vorgesehen ist.

Andere Einstellungen beziehen sich auf den Datenschutz, den Medieninhalt, Benachrichtigungen, den Hintergrund und andere Eigenschaften dieser Anwendung. Mädchen werden definitiv einen anderen Hintergrund wählen - zum Beispiel mit Katzen. Insgesamt stehen 14 Optionen zur Verfügung, Sie können keine eigenen herunterladen.

Besuchen Sie auf jeden Fall von Zeit zu Zeit den Bereich Medien. Hier können Sie den Cache leeren und so einen Teil des permanenten Speichers freigeben. Dies ist natürlich bei regelmäßiger Korrespondenz und Lesen einer großen Anzahl von Kanälen relevant. Auch das Kennenlernen Ihrer Datenschutzeinstellungen schadet nicht - hier können Sie verhindern, dass Kontakte Ihren Onlinestatus sehen. Dieser Abschnitt enthält auch die Schwarze Liste, auf der Spammer hinzugefügt werden. Sie können die Sperre auch aktivieren. In diesem Fall wird der Zugriff auf die Anwendung erst nach der Eingabe des Codes oder sogar nach dem Scannen des Fingerabdrucks gewährt.

Pin
Send
Share
Send
Send