Xamarin.iOS 无法在推送通知中显示照片
Posted
技术标签:
【中文标题】Xamarin.iOS 无法在推送通知中显示照片【英文标题】:Xamarin.iOS Cannot display photo in Push Notification 【发布时间】:2019-01-29 00:37:58 【问题描述】:我有一个通知服务扩展和一个 AppGroup。我将相机中的照片保存在 PCL 项目中,并将其复制到 App Group Container(共享文件夹)。
在通知服务扩展中,我尝试从 App Group 容器中下载照片并将其附加到通知中,但它并未显示在通知中。
我也无法调试服务扩展以查看发生了什么。据我所知,除非有人可以纠正我,否则目前在 Xamarin 中是不可能的。
代码如下:
1.在我的 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.在我的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.最后在通知服务扩展中,我尝试将照片附加到推送通知中:
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);
【问题讨论】:
【参考方案1】:/private/var/mobile/Containers/Shared/AppGroup/12F209B9-05E9-470C-9C9F-AA959D940302/Pictures/customphoto.jpg
从共享代码中,当图像从 AppGroup 中获取时。您可以检查文件路径是否在该项目中有效。
imgPath = groupUserDefaults.StringForKey("imageAbsoluteString");
如果没有从该路径获取文件。您可以直接从AppGroup
获取Url
。示例如下:
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");
);
【讨论】:
以上是关于Xamarin.iOS 无法在推送通知中显示照片的主要内容,如果未能解决你的问题,请参考以下文章