چیزهای جدید برای Web In Play

تاریخ انتشار: 2 دسامبر 2020

از زمانی که Trusted Web Activity معرفی شد، تیم Chrome استفاده از آن را با Bubblewrap آسان‌تر کرده است. ما ویژگی‌های اضافی مانند یکپارچه‌سازی صورت‌حساب Google Play را اضافه کرده‌ایم و آن را فعال کرده‌ایم تا در پلتفرم‌های بیشتری مانند ChromeOS کار کند.

ویژگی های Bubblewrap و Trusted Web Activity

Bubblewrap به شما کمک می کند تا برنامه هایی ایجاد کنید که PWA های شما را در داخل یک فعالیت وب مورد اعتماد راه اندازی کنند، بدون نیاز به دانش ابزارهای خاص پلت فرم.

جریان راه اندازی ساده شده

قبلاً، استفاده از Bubblewrap به تنظیم دستی کیت توسعه جاوا و Android SDK نیاز داشت که هر دو مستعد خطا هستند. این ابزار اکنون دانلود خودکار وابستگی های خارجی را هنگام اجرا برای اولین بار ارائه می دهد.

اگر ترجیح می‌دهید، همچنان می‌توانید از نصب موجود وابستگی‌ها استفاده کنید، و دستور doctor جدید به یافتن مشکلات کمک می‌کند و اصلاحاتی را برای پیکربندی توصیه می‌کند، که اکنون می‌تواند با استفاده از دستور updateConfig از خط فرمان به‌روزرسانی شود.

جادوگر بهبود یافته

هنگام ایجاد یک پروژه با init ، Bubblewrap برای تولید برنامه اندروید به اطلاعات نیاز دارد. این ابزار مقادیر را از Web App Manifest استخراج می کند و در صورت امکان پیش فرض ها را ارائه می دهد.

شما می توانید این مقادیر را هنگام ایجاد یک پروژه جدید تغییر دهید، اما قبلاً معنای هر فیلد مشخص نبود. گفتگوهای مقداردهی اولیه با توضیحات و اعتبارسنجی بهتر برای هر فیلد ورودی بازسازی شدند.

نمایش تمام صفحه و پشتیبانی جهت

در برخی موارد، ممکن است بخواهید برنامه شما تا حد امکان از صفحه نمایش استفاده کند و هنگام ساختن PWA، این کار با تنظیم فیلد display از مانیفست برنامه وب روی fullscreen اجرا می شود.

هنگامی که Bubblewrap گزینه تمام صفحه را در مانیفست برنامه وب شناسایی می کند، برنامه اندروید را به گونه ای پیکربندی می کند که در شرایط خاص Android نیز در حالت تمام صفحه یا حالت غوطه ور راه اندازی شود.

فیلد orientation از مانیفست برنامه وب مشخص می‌کند که آیا برنامه باید در حالت عمودی، حالت افقی یا در جهتی که دستگاه در حال حاضر از آن استفاده می‌کند شروع شود. Bubblewrap اکنون قسمت Web App Manifest را می خواند و هنگام ایجاد برنامه اندروید از آن به عنوان پیش فرض استفاده می کند.

می‌توانید هر دو bubblewrap init را سفارشی کنید.

خروجی AppBundles

App Bundles قالبی برای انتشار برنامه‌هایی است که تولید و امضای نهایی APK را به Play واگذار می‌کند. در عمل، این امکان را فراهم می کند تا فایل های کوچکتر هنگام دانلود برنامه از فروشگاه به کاربران ارائه شود.

Bubblewrap اکنون برنامه را به عنوان App Bundle در فایلی به نام app-release-bundle.aab بسته بندی می کند. هنگام انتشار برنامه‌ها در فروشگاه Play باید این قالب را ترجیح دهید، زیرا از سال 2021 فروشگاه به آن نیاز دارد .

هیأت موقعیت جغرافیایی

کاربران انتظار دارند برنامه های نصب شده بر روی دستگاه هایشان بدون توجه به فناوری، به طور مداوم رفتار کنند. هنگامی که در داخل یک فعالیت وب مورد اعتماد استفاده می شود، اکنون می توان مجوز مکان جغرافیایی را به سیستم عامل واگذار کرد و در صورت فعال بودن، کاربران همان دیالوگ های برنامه های ساخته شده با Kotlin یا جاوا را مشاهده می کنند و کنترل هایی را برای مدیریت مجوز در همان مکان پیدا می کنند.

این ویژگی را می‌توان از طریق Bubblewrap اضافه کرد و از آنجایی که وابستگی‌های اضافی به پروژه اندروید اضافه می‌کند، تنها زمانی باید آن را فعال کنید که برنامه وب از مجوز Geolocation استفاده می‌کند.

باینری های بهینه شده

دستگاه‌هایی با فضای ذخیره‌سازی محدود در مناطق خاصی از جهان رایج هستند و دارندگان آن دستگاه‌ها اغلب برنامه‌های کوچک‌تر را ترجیح می‌دهند. برنامه‌های کاربردی با استفاده از Trusted Web Activity، فایل‌های باینری کوچکی تولید می‌کنند که برخی از نگرانی‌های آن کاربران را از بین می‌برد.

Bubblewrap با کاهش لیست کتابخانه های مورد نیاز اندروید بهینه شده است و در نتیجه باینری هایی تولید می شود که 800k کوچکتر هستند. در عمل، این اندازه کمتر از نصف میانگین اندازه تولید شده توسط نسخه های قبلی است. برای استفاده از باینری های کوچکتر، فقط باید برنامه خود را با استفاده از آخرین نسخه Bubblewrap به روز کنید.

چگونه یک برنامه موجود را به روز کنیم

برنامه‌ای که توسط Bubblewrap تولید می‌شود، از یک برنامه وب و یک بسته‌بندی سبک وزن اندروید تشکیل شده است که PWA را باز می‌کند. حتی اگر PWA باز شده در یک فعالیت وب مورد اعتماد از چرخه های به روز رسانی مشابه هر برنامه وب پیروی می کند، بسته بندی اصلی می تواند و باید به روز شود.

باید برنامه خود را به‌روزرسانی کنید تا مطمئن شوید که از آخرین نسخه wrapper، با آخرین رفع اشکال و ویژگی‌ها استفاده می‌کند. با نصب آخرین نسخه Bubblewrap، دستور update آخرین نسخه wrapper را بر روی یک پروژه موجود اعمال می کند:

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

دلیل دیگر برای به‌روزرسانی این برنامه‌ها، اطمینان از اعمال تغییرات در Web Manifest در برنامه است. برای این کار از دستور 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 برای مدیریت این سناریوها را در نظر بگیرید:

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,
    });
  }
}