TWA için PostMessage

Sayed El-Abady
Sayed El-Abady

Chrome 115 sürümünden itibaren Güvenilir Web Etkinlikleri (TWA) postMessages'ı kullanarak ileti gönderebilir. Bu makalede, uygulamanız ve web arasında iletişim kurmak için gereken kurulum adım adım açıklanmıştır.

Bu rehberi tamamladığınızda: - İstemci ve web içeriği doğrulamasının nasıl çalıştığını öğreneceksiniz. - İstemci ve web içeriği arasındaki iletişim kanalını nasıl başlatacağınızı kavrayabileceksiniz. - Web içeriğine nasıl mesaj gönderileceğini ve web içeriğinden nasıl mesaj alacağını öğren.

Bu kılavuzu izlemek için şunlara ihtiyacınız vardır:

  • build.gradle dosyanıza en yeni androidx.browser (min. v1.6.0-alpha02) kitaplığını eklemek için.
  • TWA için Chrome 115.0.5790.13 veya sonraki sürümler.

window.postMessage() yöntemi, Window nesneleri arasında kaynaklar arası iletişimi güvenli bir şekilde etkinleştirir. Örneğin, bir sayfa ile oluşturduğu bir pop-up arasında veya bir sayfa ile içinde yerleşik bir iframe arasında.

Genellikle farklı sayfalardaki komut dosyalarının birbirine erişmesine izin vermek için sayfaların aynı kaynağa sahip olması ve aynı protokolü, bağlantı noktası numarasını ve ana makineyi paylaşması (aynı kaynak politikası olarak da bilinir) gerekir. window.postMessage() yöntemi, farklı kaynaklar arasında güvenli bir şekilde iletişim kurmak için kontrollü bir mekanizma sağlar. Bu sohbet uygulamaları, ortak çalışma araçları ve daha pek çok uygulama için kullanışlı olabilir. Örneğin, bir sohbet uygulaması farklı web sitelerindeki kullanıcılar arasında mesaj göndermek için postMessage uygulamasını kullanabilir. Güvenilir Web Etkinlikleri (TWA) içinde postMessage kullanımı zor olabilir. Bu kılavuz, web sayfasına ileti göndermek ve buradan ileti almak için TWA istemcisinde postMessage'ın nasıl kullanılacağı konusunda size yol gösterir.

Uygulamayı web doğrulamasına ekleyin

postMessage'ın çalışması için bir web sitesi ile bu siteyi başlatan Güvenilir Web Etkinliği uygulaması arasında geçerli bir ilişki gerekir. Bu işlem, Dijital Öğe Bağlantıları (DAL) ile, uygulamanın paket adı assetlinks.json dosyanıza use_as_origin ile ilişkili olarak eklenerek şu şekilde yapılabilir:

[{
  "relation": ["delegate_permission/common.use_as_origin"],
  "target" : { "namespace": "android_app", "package_name": "com.example.app", "sha256_cert_fingerprints": [""] }
}]

TWA ile ilişkili kaynakta kurulum, MessageEvent.origin alanı için bir kaynak sağlanmasının gerekli olduğunu ancak postMessage, Digital Assets Link içermeyen diğer sitelerle iletişim kurmak için kullanılabilir. Örneğin, www.example.com sitesinin sahibi sizseniz DAL aracılığıyla bunu kanıtlamanız gerekir, ancak diğer web siteleriyle (örneğin www.wikipedia.org) iletişim kurabilirsiniz.

PostMessageService'i manifest dosyanıza ekleyin

postMessage iletişimini almak için hizmeti ayarlamanız gerekir. Bunun için Android manifest dosyanıza PostMessageService eklemeniz gerekir:

<service android:name="androidx.browser.customtabs.PostMessageService"
android:exported="true"/>

CustomTabsSession örneği alma

Hizmeti manifest dosyasına ekledikten sonra, hizmeti bağlamak için CustomTabsClient sınıfını kullanın. Bağlandıktan sonra, sağlanan istemciyi yeni bir oturum oluşturmak için aşağıdaki şekilde kullanabilirsiniz. CustomTabsSession, postMessage API'sinin işlenmesi için kullanılan temel sınıftır. Aşağıdaki kod, hizmet bağlandıktan sonra istemcinin yeni bir oturum oluşturmak için nasıl kullanıldığını ve bu oturumun postMessage için nasıl kullanıldığını gösterir:

private CustomTabsClient mClient;
private CustomTabsSession mSession;

// We use this helper method to return the preferred package to use for
// Custom Tabs.
String packageName = CustomTabsClient.getPackageName(this, null);

// Binding the service to (packageName).
CustomTabsClient.bindCustomTabsService(this, packageName, new CustomTabsServiceConnection() {
 @Override
 public void onCustomTabsServiceConnected(@NonNull ComponentName name,
     @NonNull CustomTabsClient client) {
   mClient = client;

   // Note: validateRelationship requires warmup to have been called.
   client.warmup(0L);

   mSession = mClient.newSession(customTabsCallback);
 }

 @Override
 public void onServiceDisconnected(ComponentName componentName) {
   mClient = null;
 }
});

Şimdi bu customTabsCallback örneğinin ne olduğunu merak ediyorsunuz, değil mi? Bunu bir sonraki bölümde oluşturacağız.

CustomTabsCallback Oluştur

CustomTabsCallback, CustomTabsClient'ın kendi özel sekmelerindeki etkinliklerle ilgili mesajları almasını sağlayan bir geri çağırma sınıfıdır. Bu etkinliklerden biri olan onPostMessage, uygulama web'den mesaj aldığında çağrılır. İletişimi başlatmak amacıyla postMessage kanalını aşağıdaki kodda gösterildiği gibi başlatmak için istemciye geri çağırmayı ekleyin.

private final String TAG = "TWA/CCT-PostMessageDemo";
private Uri SOURCE_ORIGIN = Uri.parse("my-app-origin-uri");
private Uri TARGET_ORIGIN = Uri.parse("website-you-are-communicating-with");

// It stores the validation result so you can check on it before requesting postMessage channel, since without successful validation it is not posible to use postMessage.
boolean mValidated;

CustomTabsCallback customTabsCallback = new CustomTabsCallback() {

// Listens for the validation result, you can use this for any kind of
// logging purposes.
 @Override
 public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
     boolean result, @Nullable Bundle extras) {
   // If this fails:
   // - Have you called warmup?
   // - Have you set up Digital Asset Links correctly?
   // - Double check what browser you're using.
   Log.d(TAG, "Relationship result: " + result);
   mValidated = result;
 }

// Listens for any navigation happens, it waits until the navigation finishes
// then requests post message channel using
// CustomTabsSession#requestPostMessageChannel(sourceUri, targetUri, extrasBundle)

// The targetOrigin in requestPostMessageChannel means that you can be certain their messages are delivered only to the website you expect.
 @Override
 public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) {
   if (navigationEvent != NAVIGATION_FINISHED) {
     return;
   }

   if (!mValidated) {
     Log.d(TAG, "Not starting PostMessage as validation didn't succeed.");
   }

   // If this fails:
   // - Have you included PostMessageService in your AndroidManifest.xml ?
boolean result = mSession.requestPostMessageChannel(SOURCE_ORIGIN, TARGET_ORIGIN, new Bundle());
   Log.d(TAG, "Requested Post Message Channel: " + result);
 }

// This gets called when the channel we requested is ready for sending/receiving messages.
 @Override
 public void onMessageChannelReady(@Nullable Bundle extras) {
   Log.d(TAG, "Message channel ready.");

   int result = mSession.postMessage("First message", null);
   Log.d(TAG, "postMessage returned: " + result);
 }

// Listens for upcoming messages from Web.
 @Override
 public void onPostMessage(@NonNull String message, @Nullable Bundle extras) {
   super.onPostMessage(message, extras);
// Handle the received message.

 }
};

Web'den iletişim kurma

Artık barındırıcı uygulamamızdan mesaj gönderip alabiliyoruz. Aynı işlemi web'den nasıl yapabiliriz? İletişimin, barındırıcı uygulamasından başlaması ve ardından web sayfasının bağlantı noktasını ilk mesajdan alması gerekir. Bu bağlantı noktası, tekrar iletişim kurmak için kullanılır. JavaScript dosyanız aşağıdaki örneğe benzer:

window.addEventListener("message", function (event) {
  // We are receiveing messages from any origin, you can check of the origin by
  // using event.origin

  // get the port then use it for communication.
  var port = event.ports[0];
  if (typeof port === 'undefined') return;

  // Post message on this port.
  port.postMessage("Test")

  // Receive upcoming messages on this port.
  port.onmessage = function(event) {
    console.log("[PostMessage1] Got message" + event.data);
  };
});

Tam örneği burada bulabilirsiniz

Fotoğraf: Joanna Kosinska'nın Unsplash'ta