| انتخاب پلاتفرم: | iOS+ Android وب Flutter Unity C++ |
بسته به وضعیت دستگاه، پیامهای ورودی بهطور متفاوتی مدیریت میشوند. برای درک این سناریوها و نحوه ادغام FCM در برنامه خود، ابتدا مهم است که حالتهای مختلفی را که یک دستگاه میتواند در آن قرار داشته باشد، ایجاد کنید:
| ایالت | شرح |
|---|---|
| پیشزمینه | وقتی برنامه باز است، در دید است، و درحال استفاده است. |
| پسزمینه | وقتی برنامه باز است، اما در پسزمینه (کوچکشده) قرار دارد. این اتفاق معمولاً زمانی رخ میدهد که کاربر دکمه «صفحه اصلی» را در دستگاه فشار داده باشد، بااستفاده از تعویضکننده برنامه به برنامه دیگری رفته باشد، یا برنامه را در برگه دیگری (وب) باز کرده باشد. |
| فسخشده | وقتی دستگاه قفل است یا برنامه درحال اجرا نیست. |
چند پیششرط وجود دارد که باید قبلاز اینکه برنامه بتواند بااستفاده از FCM بار داده پیام را دریافت کند، برآورده شود:
- برنامه باید حداقل یکبار باز شده باشد (تا امکان ثبتنام با FCM فراهم شود).
- در iOS، اگر کاربر برنامه را از تعویضکننده برنامه تند بکشد، باید بهصورت دستی دوباره باز شود تا پیامهای پسزمینه دوباره شروع به کار کنند.
- در Android، اگر کاربر برنامه را از تنظیمات دستگاه بهاجبار ببندد، باید برنامه را بهصورت دستی باز کند تا پیامها شروع به کار کنند.
- در وب، باید با گواهینامه ارسال وب خود، یک توکن (بااستفاده از
getToken()) درخواست کرده باشید.
درخواست اجازه برای دریافت پیام
در iOS، macOS، وب، و Android نسخه ۱۳ (یا جدیدتر)، قبلاز اینکه بار دادههای FCM در دستگاهتان دریافت شود، باید ابتدا از کاربر اجازه بگیرید.
بسته firebase_messaging میانای برنامهسازی کاربردیای برای درخواست اجازه بااستفاده از
روش
requestPermission
ارائه میدهد. این API تعدادی آرگومان نامگذاریشده را میپذیرد که نوع اجازههایی را که میخواهید درخواست کنید تعریف میکنند، مثلاً اینکه آیا پیامرسانی حاوی محمولههای اعلان میتواند صدایی را فعال کند یا پیامها را بااستفاده از Siri بخواند. بهطور پیشفرض، این روش اجازههای پیشفرض معقولی را درخواست میکند. The reference API
provides full documentation on what each permission is for.
برای شروع، روش را از برنامهتان فراخوانی کنید (در iOS، یک مدال داخلی نمایش داده خواهد شد، در وب، جریان API مرورگر راهاندازی خواهد شد):
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
از ویژگی authorizationStatus شیء NotificationSettings که از درخواست برگردانده شده است میتوان برای تعیین تصمیم کلی کاربر استفاده کرد:
authorized: کاربر اجازه را اعطا کرد.denied: کاربر اجازه نداد.notDetermined: کاربر هنوز انتخاب نکرده است که اجازه را اعطا کند یا نه.provisional: کاربر اجازه موقت اعطا کرد
ویژگیهای دیگر در NotificationSettings نشان میدهند که آیا اجازه خاصی در دستگاه فعلی فعال، غیرفعال، یا پشتیبانینشده است.
پساز اعطای اجازه و درک انواع مختلف وضعیت دستگاه، برنامهتان میتواند شروع به مدیریت بارهای داده FCM ورودی کند.
مدیریت پیام
براساس وضعیت فعلی برنامهتان، بارهای ورودی انواع پیام مختلف برای مدیریت به پیادهسازیهای مختلفی نیاز دارند:
پیامهای پیشزمینه
برای مدیریت پیامها وقتی برنامهتان در پیشزمینه است، به جاریسازی onMessage گوش دهید.
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
جاریسازی حاوی RemoteMessage است که اطلاعات مختلفی را درباره بار مفید شرح میدهد، ازجمله اینکه از کجا آمده است، شناسه یکتا، زمان ارسال، اینکه آیا حاوی اعلان بوده است یا نه، و موارد دیگر. ازآنجاییکه پیام درحالی بازیابی شد که برنامهتان در پیشزمینه است، میتوانید مستقیماً به وضعیت و بافت برنامه Flutter خود دسترسی داشته باشید.
پیامهای پیشزمینه و اعلان
پیامهای اعلان که وقتی برنامه در پیشزمینه است میرسند بهطور پیشفرض، هم در Android و هم در iOS، اعلان قابلمشاهدهای را نمایش نمیدهند. بااینحال، میتوان این رفتار را لغو کرد:
- در Android، باید کانال اعلان «اولویت بالا» ایجاد کنید.
- در iOS، میتوانید گزینههای ارائه را برای برنامه بهروز کنید.
پیامهای پسزمینه
فرایند مدیریت پیامهای پسزمینه در Android، Apple، و پلاتفرمهای مبتنی بر وب متفاوت است.
پلاتفرمهای Apple و Android
با ثبت کردن یک onBackgroundMessage، پیامهای پسزمینه را مدیریت کنید. When
messages are received, an isolate is spawned (Android only, iOS/macOS does not
require a separate isolate) allowing you to handle messages even when your
application is not running.
چند نکته را باید درباره گرداننده پیام پسزمینه بهخاطر بسپارید:
- نباید تابع ناشناس باشد.
- باید تابع سطح بالا باشد (مثلاً روش کلاس نباشد که به مقداردهی اولیه نیاز دارد).
- هنگام استفاده از Flutter نسخه ۳.۳.۰ یا بالاتر، گرداننده پیام باید
درست بالای اعلان تابع با
@pragma('vm:entry-point')حاشیهنویسی شود (درغیراینصورت ممکن است درطول لرزش درخت برای حالت انتشار برداشته شود).
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
ازآنجاییکه گرداننده در ایزوله خودش خارج از بافت برنامه شما اجرا میشود، امکان بهروزرسانی وضعیت برنامه یا اجرای منطق تأثیرگذار بر واسط کاربر وجود ندارد. بااینحال، میتوانید منطقی مانند درخواستهای HTTP را اجرا کنید، عملیات IO را انجام دهید (مثلاً بهروزرسانی فضای ذخیرهسازی محلی)، با افزونههای دیگر ارتباط برقرار کنید، و غیره.
همچنین توصیه میشود منطق خود را در اسرع وقت تکمیل کنید. اجرای کارهای طولانی و فشرده بر عملکرد دستگاه تأثیر میگذارد و ممکن است باعث شود سیستمعامل فرایند را متوقف کند. اگر تکالیف بیشتر از ۳۰ ثانیه اجرا شوند، ممکن است دستگاه بهطور خودکار فرایند را متوقف کند.
وب
در وب، یک Service Worker جاوا اسکریپت بنویسید که در پسزمینه اجرا میشود. از کارگر سرویس برای مدیریت پیامهای پسزمینه استفاده کنید.
برای شروع، فایل جدیدی در فهرست راهنمای web ایجاد کنید و آن را firebase-messaging-sw.js بنامید:
// See this file for the latest firebase-js-sdk version:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_core/firebase_core_web/lib/src/firebase_sdk_version.dart
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js");
firebase.initializeApp({
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
});
const messaging = firebase.messaging();
// Optional:
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
فایل باید هم کیت توسعه نرمافزار برنامه و هم کیت توسعه نرمافزار پیامرسانی را وارد کند، Firebase را مقداردهی اولیه کند، و
متغیر messaging را نمایش دهد.
سپس، کارگر باید ثبت شود. در فایل index.html،
با اصلاح برچسب <script> که Flutter را راهاندازی میکند، کارگر را ثبت کنید:
<script src="flutter_bootstrap.js" async>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('firebase-messaging-sw.js', {
scope: '/firebase-cloud-messaging-push-scope',
});
});
}
</script>
اگر هنوز از سیستم قالببندی قدیمی استفاده میکنید، میتوانید با اصلاح برچسب <script> که Flutter را بهصورت زیر راهاندازی میکند، کارگر را ثبت کنید:
<html>
<body>
<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// Register Firebase Messaging service worker.
navigator.serviceWorker.register('firebase-messaging-sw.js', {
scope: '/firebase-cloud-messaging-push-scope',
});
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl =
'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl).then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing ?? reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});
// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.'
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
</body>
سپس برنامه Flutter را بازراهاندازی کنید. کارگر ثبت خواهد شد و هرگونه پیام پسزمینه بااستفاده از این فایل مدیریت خواهد شد.
تعامل با دستگاه
ازآنجاییکه اعلانها نشانههای قابلمشاهدهای هستند، معمولاً کاربران با آنها تعامل میکنند (با فشار دادن). رفتار پیشفرض در Android و iOS باز کردن برنامه است. اگر برنامه بسته شده باشد، راهاندازی میشود؛ اگر در پسزمینه باشد، به پیشزمینه آورده میشود.
بسته به محتوای اعلان، ممکن است بخواهید تعامل کاربر را هنگام باز شدن برنامه مدیریت کنید. برای مثال، اگر پیام گپ جدیدی بااستفاده از اعلان ارسال شود و کاربر آن را فشار دهد، ممکن است بخواهید هنگام باز شدن برنامه، مکالمه خاصی را باز کنید.
بسته firebase-messaging دو روش برای مدیریت این تعامل ارائه میدهد:
getInitialMessage(): اگر برنامه از حالت پایانیافته باز شود،FutureحاویRemoteMessageبرگردانده خواهد شد. پساز مصرف،RemoteMessageبرداشته خواهد شد.-
onMessageOpenedApp: یکStreamکه وقتی برنامه از حالت پسزمینه باز میشود،RemoteMessageرا پست میکند.
توصیه میشود هر دو سناریو مدیریت شوند تا تجربه کاربری روانی برای کاربران شما تضمین شود. نمونه کد زیر نحوه دستیابی به این هدف را نشان میدهد:
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
// It is assumed that all messages contain a data field with the key 'type'
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background using a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
if (message.data['type'] == 'chat') {
Navigator.pushNamed(context, '/chat',
arguments: ChatArguments(message),
);
}
}
@override
void initState() {
super.initState();
// Run code required to handle interacted messages in an async function
// as initState() must not be async
setupInteractedMessage();
}
@override
Widget build(BuildContext context) {
return Text("...");
}
}
نحوه مدیریت تعامل به راهاندازی برنامهتان بستگی دارد. مثال قبلی تصویرسازی سادهای را بااستفاده از StatefulWidget نشان میدهد.
بومیسازی پیامها
میتوانید رشتههای بومیسازیشده را به دو روش مختلف ارسال کنید:
- زبان ترجیحی هریک از کاربران را در سرورتان ذخیره کنید و اعلانهای سفارشیشده را برای هر زبان ارسال کنید
- رشتههای بومیسازیشده را در برنامهتان جاسازی کنید و از تنظیمات منطقه زبانی داخلی سیستمعامل استفاده کنید
نحوه استفاده از روش دوم:
Android
پیامهای زبان پیشفرض را در
resources/values/strings.xmlمشخص کنید:<string name="notification_title">Hello world</string> <string name="notification_message">This is a message</string>پیامهای ترجمهشده را در فهرست راهنمای
values-languageمشخص کنید. برای مثال، پیامهای فرانسوی را درresources/values-fr/strings.xmlمشخص کنید:<string name="notification_title">Bonjour le monde</string> <string name="notification_message">C'est un message</string>در بار داده سرور، بهجای استفاده از کلیدهای
title،message، وbody، ازtitle_loc_keyوbody_loc_keyبرای پیام بومیسازیشدهتان استفاده کنید و آنها را روی مشخصهnameپیامی که میخواهید نمایش داده شود تنظیم کنید.بار پیام به این شکل خواهد بود:
{ "android": { "notification": { "title_loc_key": "notification_title", "body_loc_key": "notification_message" } } }
iOS
پیامهای زبان پیشفرض را در
Base.lproj/Localizable.stringsمشخص کنید:"NOTIFICATION_TITLE" = "Hello World"; "NOTIFICATION_MESSAGE" = "This is a message";پیامهای ترجمهشده را در فهرست راهنمای
language.lprojمشخص کنید. برای مثال، پیامهای فرانسوی را درfr.lproj/Localizable.stringsمشخص کنید:"NOTIFICATION_TITLE" = "Bonjour le monde"; "NOTIFICATION_MESSAGE" = "C'est un message";بار پیام به این شکل خواهد بود:
{ "apns": { "payload": { "alert": { "title-loc-key": "NOTIFICATION_TITLE", "loc-key": "NOTIFICATION_MESSAGE" } } } }
فعال کردن صادر کردن دادههای تحویل پیام
میتوانید دادههای پیامتان را برای تجزیهوتحلیل بیشتر به BigQuery صادر کنید. BigQuery به شما امکان میدهد دادهها را بااستفاده از BigQuery SQL تجزیهوتحلیل کنید، آنها را به ارائهدهنده ابری دیگری صادر کنید، یا از دادهها برای مدلهای یادگیری ماشین سفارشیتان استفاده کنید. صادر کردن به BigQuery شامل همه دادههای دردسترس برای پیامها میشود، صرفنظر از نوع پیام یا اینکه پیام بااستفاده از API یا «سازنده اعلانها» ارسال شده باشد.
برای فعال کردن صادر کردن، ابتدا مراحل موجود در سند صادر کردن دادههای BigQuery را دنبال کنید. فعال کردن آن بهصورت برنامهنویسیشده در سطح نمونه برنامه به شما امکان میدهد از کاربران نهایی برای تجزیهوتحلیل دادههای تحویل پیام آنها اجازه بگیرید (توصیه میشود). برای فعال کردن صادر کردن بهصورت برنامهنویسی، این دستورالعملها را دنبال کنید:
Android
میتوانید از کد زیر استفاده کنید:
await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);
iOS
برای iOS، باید AppDelegate.m را با محتوای زیر تغییر دهید.
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Firebase/Firebase.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}
@end
وب
برای وب، باید کارگر سرویس خود را تغییر دهید تا بتوانید از نسخه v9
کیت توسعه نرمافزار استفاده کنید. نسخه v9 باید بستهبندی شود، بنابراین برای اینکه عامل خدماتی کار کند باید از بستهبندیکنندهای مثل esbuild استفاده کنید. برای دیدن نحوه دستیابی به این هدف، برنامه
نمونه
را ببینید.
پساز انتقال به کیت توسعه نرمافزار نسخه ۹، میتوانید از کد زیر استفاده کنید:
import {
experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
getMessaging,
} from 'firebase/messaging/sw';
...
const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);
فراموش نکنید yarn build را اجرا کنید تا نسخه جدید
سرویسکار را به پوشه web صادر کنید.
نمایش تصاویر در اعلانها در iOS
در دستگاههای Apple، برای اینکه «اعلانهای FCM» ورودی بتوانند تصاویر را از بار FCM نمایش دهند، باید افزونه سرویس اعلان دیگری اضافه کنید و برنامهتان را برای استفاده از آن پیکربندی کنید.
اگر از اصالتسنجی تلفن Firebase استفاده میکنید، باید Firebase Auth pod را به Podfile خود اضافه کنید.
مرحله ۱ - افزودن افزونه سرویس اعلان
- در Xcode، روی File (فایل) > New (جدید) > Target (هدف)... کلیک کنید
- یک پنجره مودال فهرستی از اهداف ممکن را ارائه میدهد؛ پیمایش کنید یا از فیلتر برای انتخاب افزونه سرویس اعلان استفاده کنید. روی بعدی کلیک کنید.
- نام محصول را اضافه کنید (برای دنبال کردن این آموزش از «ImageNotification» استفاده کنید)،
SwiftیاObjective-Cرا انتخاب کنید، و روی پایان کلیک کنید. - با کلیک کردن روی فعال کردن، طرح را فعال کنید.
مرحله ۲ - افزودن هدف به Podfile
Swift
مطمئن شوید که افزونه جدیدتان به بسته swift FirebaseMessaging دسترسی دارد. برای این کار، آن را به هدف Runner اضافه کنید:
از Navigator، کیت توسعه نرمافزار پلاتفرمهای Firebase Apple را اضافه کنید: File > Add Package Dependencies...
جستجو یا وارد کردن نشانی وب بسته:
none https://github.com/firebase/firebase-ios-sdkافزودن به پروژه
Runner: افزودن بستهFirebaseMessaging را انتخاب کنید و به ImageNotification هدف اضافه کنید: افزودن بسته
Objective-C
مطمئن شوید افزونه جدیدتان به پاد Firebase/Messaging دسترسی دارد
و آن را به Podfile اضافه کنید:
از Navigator، Podfile را باز کنید: Pods > Podfile
به پایین فایل بروید و این را اضافه کنید:
target 'ImageNotification' do use_frameworks! pod 'Firebase/Auth' # Add this line if you are using FirebaseAuth phone authentication pod 'Firebase/Messaging' endپادهایتان را بااستفاده از
pod installاز فهرست راهنمایiosیاmacosنصب یا بهروز کنید.
مرحله ۳ - استفاده از راهنمای افزونه
در این مرحله، همه چیز باید همچنان بهطور عادی اجرا شود. مرحله نهایی فراخوانی دستیار افزونه است.
Swift
از ناوبر، افزونه ImageNotification را انتخاب کنید
فایل
NotificationService.swiftرا باز کنید.محتوای
NotificationService.swiftبا این مورد جایگزین شود:import UserNotifications import FirebaseMessaging class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) Messaging.serviceExtension().populateNotificationContent(bestAttemptContent!, withContentHandler: contentHandler) } override func serviceExtensionTimeWillExpire() { if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
Objective-C
از ناوبر، افزونه ImageNotification را انتخاب کنید
فایل
NotificationService.mرا باز کنید.در بالای فایل،
FirebaseMessaging.hرا درست بعدازNotificationService.hوارد کنید.محتوای
NotificationService.mبا این مورد جایگزین شود:#import "NotificationService.h" #import "FirebaseMessaging.h" #import <FirebaseAuth/FirebaseAuth-Swift.h> // Add this line if you are using FirebaseAuth phone authentication #import <UIKit/UIKit.h> // Add this line if you are using FirebaseAuth phone authentication @interface NotificationService () <NSURLSessionDelegate> @property(nonatomic) void (^contentHandler)(UNNotificationContent *contentToDeliver); @property(nonatomic) UNMutableNotificationContent *bestAttemptContent; @end @implementation NotificationService /* Uncomment this if you are using Firebase Auth - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options { if ([[FIRAuth auth] canHandleURL:url]) { return YES; } return NO; } - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts { for (UIOpenURLContext *urlContext in URLContexts) { [FIRAuth.auth canHandleURL:urlContext.URL]; } } */ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // Modify the notification content here... [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler]; } - (void)serviceExtensionTimeWillExpire { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. self.contentHandler(self.bestAttemptContent); } @end
مرحله ۴ - افزودن تصویر به پایهبار
اکنون میتوانید به محموله اعلان خود تصویر اضافه کنید. برای کسب اطلاعات بیشتر، نحوه ساختن درخواست ارسال را ببینید.