Xamarin.iOS 无法在推送通知中显示照片

Xamarin.iOS Cannot display photo in Push Notification

我有一个通知服务扩展和一个 AppGroup。我将相机拍摄的照片保存在 PCL 项目中,并将其复制到 App Group Container(共享文件夹)。

在 Notification Service Extension 中,我尝试从 App Group 容器下载照片并将其附加到通知中,但它只是没有显示在通知中。

我也无法调试服务扩展以查看发生了什么。据我所知,目前在 Xamarin 中这是不可能的,除非有人可以纠正我。

代码如下:

1.in 我的 PCL 我在按下保存按钮时将照片保存到 AppGroup:

 private void ButtonSavePhoto_Clicked(object sender, EventArgs e)
            {
                if (!string.IsNullOrEmpty(photoFilePath))
                {
                    Preferences.Set(AppConstants.CUSTOM_PICTURE_FILE_PATH, photoFilePath);
                    Preferences.Set(AppConstants.CUSTOM_PHOTO_SET_KEY, true);

                    if (Device.RuntimePlatform == Device.iOS)
                    {

                        bool copiedSuccessfully = DependencyService.Get<IPhotoService>().CopiedFileToAppGroupContainer(photoFilePath);

                        if (copiedSuccessfully)
                        {
                            var customPhotoDestPath = DependencyService.Get<IPhotoService>().GetAppContainerCustomPhotoFilePath();

                            // save the path of the custom photo in the AppGroup container to pass to Notif Extension Service
                            DependencyService.Get<IGroupUserPrefs>().SetStringValueForKey("imageAbsoluteString", customPhotoDestPath);

                            // condition whether to use custom photo in push notification
                            DependencyService.Get<IGroupUserPrefs>().SetBoolValueForKey("isCustomPhotoSet", true);
                        }
                    }

                    buttonSavePhoto.IsEnabled = false;
                }         
            }

2.in 我的 iOS 项目,依赖注入在按下保存按钮时调用此方法:

    public bool CopiedFileToAppGroupContainer(string filePath)
    {
                bool success = false;

                string suiteName = "group.com.company.appName";
                var appGroupContainerUrl = NSFileManager.DefaultManager.GetContainerUrl(suiteName);

                var appGroupContainerPath = appGroupContainerUrl.Path;

                var directoryNameInAppGroupContainer = Path.Combine(appGroupContainerPath, "Pictures");

                var filenameDestPath = Path.Combine(directoryNameInAppGroupContainer, AppConstants.CUSTOM_PHOTO_FILENAME);

                try
                {
                    Directory.CreateDirectory(directoryNameInAppGroupContainer);

                    if (File.Exists(filenameDestPath))
                    {
                        File.Delete(filenameDestPath);
                    }

                    File.Copy(filePath, filenameDestPath);
                    success = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

                return success;
            }

现在 App Group 容器中照片的路径为:

/private/var/mobile/Containers/Shared/AppGroup/12F209B9-05E9-470C-9C9F-AA959D940302/Pictures/customphoto.jpg

3.Finally 在通知服务扩展中我尝试将照片附加到推送通知:

public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
        {
            ContentHandler = contentHandler;
            BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();

            string imgPath;
            NSUrl imgUrl;

            string notificationBody = BestAttemptContent.Body;
            string notifBodyInfo = "unknown";

            string suiteName = "group.com.company.appname";  

            NSUserDefaults groupUserDefaults = new NSUserDefaults(suiteName, NSUserDefaultsType.SuiteName);           

            string pref1_value = groupUserDefaults.StringForKey("user_preference1");

            string[] notificationBodySplitAtDelimiterArray = notificationBody.Split(',');
            userPrefRegion = notificationBodySplitAtDelimiterArray[0];

            bool isCustomAlertSet = groupUserDefaults.BoolForKey("isCustomAlert");
            bool isCustomPhotoSet = groupUserDefaults.BoolForKey("isCustomPhotoSet");

            string alarmPath = isCustomAlertSet == true ? "customalert.wav" : "default_alert.m4a";

            if (isCustomPhotoSet)
            {
                 // this is the App Group url of the custom photo saved in PCL
                 imgPath = groupUserDefaults.StringForKey("imageAbsoluteString");             
            }
            else
            {
                imgPath = null;
            }

            if (imgPath != null )
            {                
                imgUrl = NSUrl.FromString(imgPath);
            }
            else
            {
                imgUrl = null;
            }

            if (!string.IsNullOrEmpty(pref1_value))
            {
                if (BestAttemptContent.Body.Contains(pref1_value))
                {

                   if (imgUrl != null)
                   {

                        // download the image from the AppGroup Container
                        var task = NSUrlSession.SharedSession.CreateDownloadTask(imgUrl, (tempFile, response, error) =>
                        {
                            if (error != null)
                            {                             
                                ContentHandler(BestAttemptContent);
                                return;
                            }
                            if (tempFile == null)
                            {
                                ContentHandler(BestAttemptContent);
                                return;
                            }

                            var cache = NSSearchPath.GetDirectories(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomain.User, true);
                            var cachesFolder = cache[0];
                            var guid = NSProcessInfo.ProcessInfo.GloballyUniqueString;
                            var fileName = guid + "customphoto.jpg";
                            var cacheFile = cachesFolder + fileName;
                            var attachmentUrl = NSUrl.CreateFileUrl(cacheFile, false, null);

                            NSError err = null;
                            NSFileManager.DefaultManager.Copy(tempFile, attachmentUrl, out err);

                            if (err != null)
                            {
                                ContentHandler(BestAttemptContent);
                                return;
                            }

                            UNNotificationAttachmentOptions options = null;
                            var attachment = UNNotificationAttachment.FromIdentifier("image", attachmentUrl, options, out err);

                            if (attachment != null)
                            {
                                BestAttemptContent.Attachments = new UNNotificationAttachment[] { attachment };
                            }    
                        });
                        task.Resume();
                   }                                        
                    BestAttemptContent.Title = "My Custom Title";
                    BestAttemptContent.Subtitle = "My Custom Subtitle";
                    BestAttemptContent.Body = "Notification Body";
                    BestAttemptContent.Sound = UNNotificationSound.GetSound(alarmPath);        
                }                 
            }
            else
            {
               pref1_value = "error getting extracting user pref";
            }        

            // finally display customized notification                 
            ContentHandler(BestAttemptContent);
        }

/private/var/mobile/Containers/Shared/AppGroup/12F209B9-05E9-470C-9C9F-AA959D940302/Pictures/customphoto.jpg

来自共享代码,当图像从 AppGroup 获取时。您可以检查文件路径是否在该项目中工作。

imgPath = groupUserDefaults.StringForKey("imageAbsoluteString"); 

如果没有从此路径获取文件。您可以从 AppGroup 得到 Url directly.Here 是一个示例,如下所示:

var FileManager = new NSFileManager();
var appGroupContainer = FileManager.GetContainerUrl("group.com.company.appName");
NSUrl fileURL = appGroupContainer.Append("customphoto.jpg", false);

而如果fileURL不能直接使用,也可以转换为NSData保存到本地文件系统。这个也可以试试

下面是从本地文件系统抓取的示例:

public static void Sendlocalnotification()
{       
    var localURL = "...";
    NSUrl url = NSUrl.FromString(localURL) ;

    var attachmentID = "image";
    var options = new UNNotificationAttachmentOptions();
    NSError error;
    var attachment = UNNotificationAttachment.FromIdentifier(attachmentID, url, options,out error);


    var content = new UNMutableNotificationContent();
    content.Attachments = new UNNotificationAttachment[] { attachment };
    content.Title = "Good Morning ~";
    content.Subtitle = "Pull this notification ";
    content.Body = "reply some message-BY Ann";
    content.CategoryIdentifier = "message";

    var trigger1 = UNTimeIntervalNotificationTrigger.CreateTrigger(0.1, false);

    var requestID = "messageRequest";
    var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger1);

    UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
     {
         if (err != null)
         {
             Console.Write("Notification Error");
         }
     });

}