What's new for Web In Play

প্রকাশিত: ২ ডিসেম্বর, ২০২০

বিশ্বস্ত ওয়েব অ্যাক্টিভিটি চালু হওয়ার পর থেকে, Chrome টিম Bubblewrap-এর সাথে এটি ব্যবহার করা আরও সহজ করে তুলেছে। আমরা অতিরিক্ত ফিচার যোগ করেছি, যেমন Google Play Billing ইন্টিগ্রেশন এবং ChromeOS-এর মতো আরও প্ল্যাটফর্মে কাজ করার জন্য এটি চালু করেছি।

Bubblewrap এবং বিশ্বস্ত ওয়েব অ্যাক্টিভিটি ফিচার

Bubblewrap আপনাকে এমন অ্যাপ তৈরি করতে সাহায্য করে যা প্ল্যাটফর্ম-নির্দিষ্ট টুলিং সম্পর্কে জ্ঞান ছাড়াই বিশ্বস্ত ওয়েব অ্যাক্টিভিটির মধ্যে আপনার PWA চালু করে।

সহজ সেট-আপ ফ্লো

আগে, Bubblewrap ব্যবহার করার জন্য Java Development Kit এবং Android SDK ম্যানুয়ালি সেট-আপ করতে হত, যেখানে ভুল হওয়ার সম্ভাবনা বেশি ছিল। টুলটি এখন প্রথমবার চালানোর সময় এক্সটার্নাল ডিপেন্ডেন্সি অটোমেটিক ডাউনলোড করার সুবিধা অফার করে।

আপনি চাইলে এখনও ডিপেন্ডেন্সির আগে থেকে থাকা ইনস্টলেশন ব্যবহার করতে পারেন, এবং নতুন doctor কমান্ড সমস্যা খুঁজে পেতে সাহায্য করে এবং কনফিগারেশনে সমাধান সাজেস্ট করে, যা এখন updateConfig কমান্ড ব্যবহার করে কমান্ড লাইন থেকে আপডেট করা যেতে পারে।

উন্নত উইজার্ড

init-এর সাহায্যে প্রোজেক্ট তৈরি করার সময়, Android অ্যাপ তৈরি করার জন্য Bubblewrap-এর তথ্য প্রয়োজন হয়। টুলটি ওয়েব অ্যাপ ম্যানিফেস্ট থেকে ভ্যালু এক্সট্র্যাক্ট করে এবং যেখানে সম্ভব ডিফল্ট ভ্যালু প্রদান করে।

নতুন প্রোজেক্ট তৈরি করার সময় আপনি এইসব ভ্যালু পরিবর্তন করতে পারবেন, তবে আগে প্রতিটি ফিল্ডের অর্থ স্পষ্ট ছিল না। ইনিশিয়ালাইজেশন ডায়ালগগুলি আরও ভালো বিবরণ এবং প্রতিটি ইনপুট ফিল্ডের জন্য যাচাইকরণ সহ পুনর্নির্মাণ করা হয়েছে।

ফুলস্ক্রিন ও ওরিয়েন্টেশন সাপোর্ট দেখান

কিছু ক্ষেত্রে, আপনি হয়ত চাইবেন যে আপনার অ্যাপ্লিকেশন যেন স্ক্রিনের যতটা সম্ভব জায়গা ব্যবহার করে এবং PWA তৈরি করার সময়, এটি ওয়েব অ্যাপ ম্যানিফেস্ট থেকে display ফিল্ডকে fullscreen-এ সেট করার মাধ্যমে প্রয়োগ করা হয়।

Bubblewrap যখন ওয়েব অ্যাপ ম্যানিফেস্টে ফুল-স্ক্রিন বিকল্প শনাক্ত করে, তখন এটি Android অ্যাপ্লিকেশনকে ফুল-স্ক্রিনে বা Android-এর নির্দিষ্ট পরিভাষায় ইমারসিভ মোডে লঞ্চ করার জন্য কনফিগার করে।

ওয়েব অ্যাপ ম্যানিফেস্টের orientation ফিল্ড থেকে জানা যায় যে অ্যাপ্লিকেশনটি পোর্ট্রেট মোড, ল্যান্ডস্কেপ মোড নাকি ডিভাইসটি বর্তমানে যে ওরিয়েন্টেশন ব্যবহার করছে, সেই মোডে চালু করা উচিত। Bubblewrap এখন ওয়েব অ্যাপ ম্যানিফেস্ট ফিল্ড পড়ে এবং Android অ্যাপ তৈরি করার সময় এটি ডিফল্ট হিসেবে ব্যবহার করে।

bubblewrap init ফ্লোয়ের অংশ হিসেবে আপনি দুটি কনফিগারেশনই কাস্টমাইজ করতে পারবেন।

AppBundles আউটপুট

অ্যাপ বান্ডেল হল অ্যাপের জন্য একটি প্রকাশনা ফর্ম্যাট যা চূড়ান্ত APK তৈরি এবং Play-তে সাইন করার দায়িত্ব দেয়। ব্যবহারিকভাবে, এর ফলে স্টোর থেকে অ্যাপ ডাউনলোড করার সময় ব্যবহারকারীদের ছোট ফাইল পরিবেশন করা সম্ভব হয়।

Bubblewrap এখন অ্যাপ্লিকেশনটিকে একটি অ্যাপ বান্ডেল হিসেবে প্যাকেজ করে, app-release-bundle.aab নামের একটি ফাইলে। Play Store-এ অ্যাপ প্রকাশ করার সময় এই ফর্ম্যাট ব্যবহার করা উচিত, কারণ ২০২১ সাল থেকে স্টোরে এটি ব্যবহার করা বাধ্যতামূলক।

ভৌগোলিক অবস্থান সংক্রান্ত ডেলিগেশন

ব্যবহারকারীরা আশা করেন যে তাদের ডিভাইসে ইনস্টল করা অ্যাপ্লিকেশনগুলি প্রযুক্তি নির্বিশেষে ধারাবাহিকভাবে কাজ করবে। বিশ্বস্ত ওয়েব অ্যাক্টিভিটির মধ্যে ব্যবহার করা হলে, GeoLocation সংক্রান্ত অনুমতি এখন অপারেটিং সিস্টেমকে ডেলিগেট করা যেতে পারে এবং চালু করা হলে, Kotlin বা Java দিয়ে তৈরি অ্যাপের মতো একই ডায়ালগ ব্যবহারকারীরা দেখতে পান এবং একই জায়গায় অনুমতি ম্যানেজ করার কন্ট্রোল খুঁজে পান।

Bubblewrap-এর মাধ্যমে ফিচারটি যোগ করা যেতে পারে এবং এটি Android প্রোজেক্টে অতিরিক্ত ডিপেন্ডেন্সি যোগ করে বলে, ওয়েব অ্যাপটি জিওলোকেশন অনুমতি ব্যবহার করলে তবেই এটি চালু করা উচিত।

অপ্টিমাইজ করা বাইনারি

সীমিত স্টোরেজ সহ ডিভাইসগুলি বিশ্বের নির্দিষ্ট কিছু অঞ্চলে সাধারণ এবং সেইসব ডিভাইসের মালিকরা প্রায়শই ছোট অ্যাপ্লিকেশন পছন্দ করেন। বিশ্বস্ত ওয়েব অ্যাক্টিভিটি ব্যবহার করে এমন অ্যাপ্লিকেশন ছোট বাইনারি তৈরি করে, যা ব্যবহারকারীদের উদ্বেগ কিছুটা কমায়।

প্রয়োজনীয় Android লাইব্রেরির তালিকা কমিয়ে Bubblewrap অপ্টিমাইজ করা হয়েছে, যার ফলে জেনারেট করা বাইনারি ৮০০k ছোট হয়েছে। বাস্তবে, এটি আগের ভার্সন দ্বারা জেনারেট করা গড় সাইজের অর্ধেকেরও কম। ছোট বাইনারির সুবিধা নিতে, আপনাকে শুধু Bubblewrap-এর লেটেস্ট ভার্সন ব্যবহার করে আপনার অ্যাপ আপডেট করতে হবে।

আগে থেকে থাকা অ্যাপ কীভাবে আপডেট করবেন

Bubblewrap-এর মাধ্যমে তৈরি করা অ্যাপ্লিকেশন, ওয়েব অ্যাপ্লিকেশন ও লাইটওয়েট Android র‌্যাপার নিয়ে গঠিত যা PWA খোলে। যদিও বিশ্বস্ত ওয়েব অ্যাক্টিভিটির মধ্যে খোলা PWA যেকোনও ওয়েব অ্যাপের মতো একই আপডেট সাইকেল অনুসরণ করে, নেটিভ র‍্যাপার আপডেট করা যেতে পারে এবং করা উচিত।

আপনার অ্যাপ আপডেট করা উচিত যাতে এটি লেটেস্ট ত্রুটি সমাধান ও ফিচার সহ র‍্যাপারের লেটেস্ট ভার্সন ব্যবহার করছে কিনা তা নিশ্চিত করা যায়। Bubblewrap-এর লেটেস্ট ভার্সন ইনস্টল করা থাকলে, update কমান্ডটি আগে থেকে থাকা প্রোজেক্টে র‍্যাপারের লেটেস্ট ভার্সন প্রয়োগ করে:

npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build

এইসব অ্যাপ্লিকেশন আপডেট করার আরেকটি কারণ হল, ওয়েব ম্যানিফেস্টে করা পরিবর্তনগুলি অ্যাপ্লিকেশনে প্রয়োগ করা হয়েছে কিনা তা নিশ্চিত করা। তার জন্য নতুন merge কমান্ড ব্যবহার করুন:

bubblewrap merge
bubblewrap update
bubblewrap build

কোয়ালিটি সংক্রান্ত মাপকাঠিতে আপডেট

Chrome 86-এ বিশ্বস্ত ওয়েব অ্যাক্টিভিটির কোয়ালিটি সংক্রান্ত মাপকাঠিতে পরিবর্তন করা হয়েছে, যা বিশ্বস্ত ওয়েব অ্যাক্টিভিটি ব্যবহার করে PWA-এর জন্য কোয়ালিটি সংক্রান্ত মাপকাঠিতে পরিবর্তন-এ সম্পূর্ণভাবে ব্যাখ্যা করা হয়েছে।

সংক্ষেপে বলতে গেলে, আপনার অ্যাপ্লিকেশন যাতে ক্র্যাশ না করে তার জন্য নিম্নলিখিত পরিস্থিতিগুলি ম্যানেজ করতে হবে:

  • অ্যাপ্লিকেশন লঞ্চ করার সময় ডিজিটাল অ্যাসেট লিঙ্ক যাচাই করা যায়নি
  • অফলাইন নেটওয়ার্ক রিসোর্স অনুরোধের জন্য HTTP 200 রিটার্ন করা যায়নি
  • অ্যাপ্লিকেশনে HTTP 404 বা 5xx সমস্যা ফিরে আসা।

অ্যাপ্লিকেশনটি ডিজিটাল অ্যাসেট লিঙ্ক যাচাইকরণ পাস করেছে কিনা তা নিশ্চিত করার পাশাপাশি, বাকি পরিস্থিতিগুলি একজন পরিষেবা কর্মী দ্বারা পরিচালনা করা যেতে পারে:

self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    try {
      return await fetchAndHandleError(event.request);
    } catch {
      // Failed to load from the network. User is offline or the response
      // has a status code that triggers the Quality Criteria.
      // Try loading from cache.
      const cachedResponse = await caches.match(event.request);
      if (cachedResponse) {
        return cachedResponse;
      }
      // Response was not found on the cache. Send the error / offline
      // page. OFFLINE_PAGE should be pre-cached when the service worker
      // is activated.
      return await caches.match(OFFLINE_PAGE);
    }
  })());
});

async function fetchAndHandleError(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  const response = await fetch(request);

  // Throw an error if the response returns one of the status
  // that trigger the Quality Criteria.
  if (response.status === 404 ||
      response.status >= 500 && response.status < 600) {
    throw new Error(`Server responded with status: ${response.status}`);
  }

  // Cache the response if the request is successful.
  cache.put(request, response.clone());
  return response;
}

Workbox পেশাদার পদ্ধতি ব্যবহার করে এবং সার্ভিস ওয়ার্কার ব্যবহার করার সময় বয়লারপ্লেট সরিয়ে দেয়। বিকল্প হিসেবে, এইসব পরিস্থিতি ম্যানেজ করতে Workbox প্লাগ-ইন ব্যবহার করার কথা বিবেচনা করুন:

export class FallbackOnErrorPlugin {
  constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) {
    this.notFoundFallbackUrl = notFoundFallbackUrl;
    this.offlineFallbackUrl = offlineFallbackUrl;
    this.serverErrorFallbackUrl = serverErrorFallbackUrl;
  }

  checkTrustedWebActivityCrash(response) {
    if (response.status === 404 || response.status >= 500 && response.status <= 600) {
      const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR';
      const error = new Error(`Invalid response status (${response.status})`);
      error.type = type;
      throw error;
    }
  }

  // This is called whenever there's a network response,
  // but we want special behavior for 404 and 5**.
  fetchDidSucceed({response}) {
    // Cause a crash if this is a Trusted Web Activity crash.
    this.checkTrustedWebActivityCrash(response);

    // If it's a good response, it can be used as-is.
    return response;
  }

  // This callback is new in Workbox v6, and is triggered whenever
  // an error (including a NetworkError) is thrown when a handler runs.
  handlerDidError(details) {
    let fallbackURL;
    switch (details.error.details.error.type) {
      case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break;
      case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break;
      default: fallbackURL = this.offlineFallbackUrl;
    }

    return caches.match(fallbackURL, {
      // Use ignoreSearch as a shortcut to work with precached URLs
      // that have _WB_REVISION parameters.
      ignoreSearch: true,
    });
  }
}