Я не могу использовать Xamarin.Essentials для захвата координат пользователя в проекте расширения уведомлений , но, конечно, он отлично работает в основном iOS проекте.
Я знаю Расширение службы уведомлений ограничено в функциональности (насколько я знаю), но я хотел бы, чтобы в качестве функциональности для моего приложения была возможность настроить уведомление pu sh для пользователя в зависимости от его местоположения на данный момент. когда они получают уведомление pu sh (что-то вроде геозоны).
В качестве альтернативного способа я пытался всегда записывать и непрерывно перезаписывать местоположение пользователя (как только они предлагали разрешение «Всегда» для местоположения) в Основной проект и сохранить координаты в контейнере APP GROUP, откуда я могу получить их в проекте Extension, но это не удастся, если пользователь убьет приложение, оно будет работать только в том случае, если приложение находится в фоновом режиме.
Но это не совсем то, что я хочу, в идеале я бы просто получал координаты, когда пользователь получает уведомление в проекте расширения, когда оно активируется входящим уведомлением (поэтому независимо от того, убивает ли пользователь приложение).
Да, я знаю, что существуют ограничения конфиденциальности, но для варианта использования, для которого мне это нужно, есть очень веская причина, чтобы иметь возможность получить местоположение пользователя при поступлении уведомления, даже если пользователь убитое приложение.
То, что я пробовал до сих пор и НЕ работает из того, что я тестировал, если пользователь убивает приложение (потому что, скорее всего, LocationUpated перестает срабатывать после того, как пользователь убивает приложение):
В основном проекте Xamarin. iOS:
public class LocationUpdatedEventArgs : EventArgs
{
private CLLocation location;
iOSGroupUserPrefsService prefService = new iOSGroupUserPrefsService();
public LocationUpdatedEventArgs(CLLocation location)
{
this.location = location;
//this.prefService = new iOSGroupUserPrefsService();
prefService.SetStringValueForKey("longitude", this.Location.Coordinate.Longitude.ToString());
prefService.SetStringValueForKey("latitude", this.Location.Coordinate.Latitude.ToString());
}
public CLLocation Location
{
get { return location; }
}
}
В проекте расширения уведомлений:
[Register("NotificationService")]
public class NotificationService : UNNotificationServiceExtension
{
private Action<UNNotificationContent> ContentHandler { get; set; }
private UNMutableNotificationContent BestAttemptContent { get; set; }
protected NotificationService(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
{
ContentHandler = contentHandler;
BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();
NSError error = null;
NSError attachmentError = null;
string notificationBody = BestAttemptContent.Body;
string suiteName = "group.com.company.myapp";
NSUserDefaults groupUserDefaults = new NSUserDefaults(suiteName, NSUserDefaultsType.SuiteName);
var appGroupContainerUrl = NSFileManager.DefaultManager.GetContainerUrl(suiteName);
double _dblLongConv, _dblLatConv;
_dblLongConv = _dblLatConv = 0.0;
string longitude = groupUserDefaults.StringForKey("longitude");
string latitude = groupUserDefaults.StringForKey("latitude");
if (!string.IsNullOrEmpty(longitude) && !string.IsNullOrEmpty(latitude))
{
bool success = Double.TryParse(longitude, out double dblLong);
if (success)
{
_dblLongConv = dblLong;
}
success = Double.TryParse(latitude, out double dblLat);
if (success)
{
_dblLatConv = dblLat;
}
}
BestAttemptContent.Title = ExtensionAppConstants.SHAKEOUT_TITLE_TEXT;
BestAttemptContent.Subtitle = ExtensionAppConstants.SHAKEOUT_SUBTITLE_TEXT;
BestAttemptContent.Body = "Long: " + _dblLongConv + " Lat: " + _dblLatConv;
BestAttemptContent.Sound = UNNotificationSound.GetSound(alarmPath);
UNNotificationAttachment attachment = UNNotificationAttachment.FromIdentifier("", new NSUrl(localPath, false), options: null, error: out attachmentError);
if (attachmentError == null)
{
BestAttemptContent.Attachments = new UNNotificationAttachment[] { attachment };
}
ContentHandler(BestAttemptContent);
}
public override void TimeWillExpire()
{
// 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.
ContentHandler(BestAttemptContent);
}
}