如何在Xamarin.iOS中显示Azure通知中心推送的带图通知(无服务扩展)
Displaying Image Attachments in Xamarin.iOS Foreground Notifications (DidReceiveRemoteNotification)
I get it, the official docs can feel pretty dense when you're trying to add images to notifications without using a service extension. Let's break this down and modify your existing DidReceiveRemoteNotification method to show notifications with images when your app is in the foreground.
Key Things to Know
- When your app is active (foreground), iOS doesn't automatically show a notification banner—you have to create and present the notification manually using
UNUserNotificationCenter. - Notification attachments require local files, so we'll need to download the image from your backend's URL to a temporary local file first.
Modified Code Example
Here's how to update your method to handle image attachments:
using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; using Foundation; using UIKit; using UserNotifications; // Ensure your delegate inherits from UNUserNotificationCenterDelegate public class YourNotificationDelegate : UNUserNotificationCenterDelegate { public override async void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action completionHandler) { NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary; NSDictionary detailedInfo = aps?.ObjectForKey(new NSString("alert")) as NSDictionary; NSDictionary custom = userInfo.ObjectForKey(new NSString("custom")) as NSDictionary; // Define your payload keys var messageTitleKey = new NSString("title"); var messageBodyKey = new NSString("body"); var orderIdKey = new NSString("orderid"); var pageToNavigateKey = new NSString("page"); var notificationDbIdKey = new NSString("notificationDbId"); var imageUrlKey = new NSString("image_url"); // Add this key for your image URL in the custom payload LinkNavigation linkNavigation = new LinkNavigation(); string message = null, orderId = null, page = null, notificationId = null, imageUrl = null; // Extract existing payload data if (detailedInfo != null && detailedInfo.ContainsKey(messageBodyKey)) { message = (detailedInfo[messageBodyKey] as NSString).ToString(); } if (custom != null) { if (custom.ContainsKey(orderIdKey)) { orderId = (custom[orderIdKey] as NSString).ToString(); linkNavigation.OrderId = !string.IsNullOrEmpty(orderId) ? orderId : null; } if (custom.ContainsKey(pageToNavigateKey)) { page = (custom[pageToNavigateKey] as NSString).ToString(); if (!string.IsNullOrEmpty(page)) { linkNavigation.Pagename = Convert.ToInt16(page); } } if (custom.ContainsKey(notificationDbIdKey)) { notificationId = (custom[notificationDbIdKey] as NSString).ToString(); if (!string.IsNullOrEmpty(notificationId)) { NotificationReadUnread(long.Parse(notificationId)); } } // Extract the image URL from your custom payload if (custom.ContainsKey(imageUrlKey)) { imageUrl = (custom[imageUrlKey] as NSString).ToString(); } } // Handle app navigation as before if (!string.IsNullOrEmpty(orderId) || !string.IsNullOrEmpty(page)) { LoadApplication(new App(linkNavigation)); } // Show notification with image if we have a valid URL and app is active if (!string.IsNullOrEmpty(imageUrl) && application.ApplicationState == UIApplicationState.Active) { try { // Step 1: Download the image from the URL using (var httpClient = new HttpClient()) { byte[] imageData = await httpClient.GetByteArrayAsync(imageUrl); // Step 2: Save image to a temporary directory (required for notifications) string tempDir = Path.Combine(NSTemporaryDirectory(), "NotificationImages"); Directory.CreateDirectory(tempDir); string filePath = Path.Combine(tempDir, $"notification_img_{Guid.NewGuid()}.jpg"); File.WriteAllBytes(filePath, imageData); // Step 3: Create a UNNotificationAttachment from the local file var attachmentOptions = new UNNotificationAttachmentOptions(); UNNotificationAttachment attachment = await UNNotificationAttachment.CreateAsync( identifier: "image_attachment", url: NSUrl.FromFilename(filePath), options: attachmentOptions); // Step 4: Build the notification content var notificationContent = new UNMutableNotificationContent(); notificationContent.Title = detailedInfo?[messageTitleKey]?.ToString() ?? "New Notification"; notificationContent.Body = message ?? "You have a new message"; notificationContent.Attachments = new[] { attachment }; // Step 5: Create and present the notification var request = UNNotificationRequest.FromIdentifier( identifier: $"notification_{Guid.NewGuid()}", content: notificationContent, trigger: null); // Trigger immediately await UNUserNotificationCenter.Current.AddNotificationRequestAsync(request); } } catch (Exception ex) { // Log any errors (e.g., failed download, invalid image format) Console.WriteLine($"Error showing image notification: {ex.Message}"); } } // Don't forget to call the completion handler completionHandler(); } // Your existing NotificationReadUnread method and other helper code here private void NotificationReadUnread(long notificationId) { // Your implementation } }
Important Notes
- Payload Structure: Make sure your backend sends the image URL in the
customsection of the payload under the keyimage_url(adjust the key name in the code if your backend uses a different one). - Permissions: Ensure you've requested user permission for notifications in your app startup code:
var center = UNUserNotificationCenter.Current; await center.RequestAuthorizationAsync(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge); - Image Requirements: The image should be in a supported format (JPG, PNG, GIF), and the URL should be publicly accessible. If it's a private URL, modify the HttpClient call to include authentication headers.
- Temporary Files: We're using the app's temporary directory to store the image—iOS will clean this up automatically, so no need to worry about leftover files.
内容的提问来源于stack exchange,提问作者Sneha Das
相关产品推荐
相关产品推荐

