2017-01-02 5 views
13

У меня проблема с расширением службы уведомлений. Я выполнил следующие этапы:Устранение проблемы с расширением уведомлений Xamarin

Чтобы реализовать, я сделал так.

  • Добавлено Notification Service Extension с таким же префиксом мое приложение (добавление суффикса, например: APP: com.testapp.main - EXT: com.testapp.main.notificationextension)
  • Создан APPID идентификатор com.testapp .main.notificationextension в центр членов компании Apple
  • создал сертификат и профиля обеспечения для отправки толчок уведомления для APP ID com.testapp.main.notificationextension
  • Импортируется в Xcode и Xamarin сертификат и инициализации
  • построить мое приложение со ссылкой к уведомлению Exte ссылка.
  • создал архив для того, чтобы TestFlight
  • Подпись приложения с сертификатом распределения и Provisioning Profile
  • Подпись расширение с сертификатом распределения и Provisioning Profile
  • Загрузил в TestFlight
  • Скачать и позволил толчок уведомление для моего приложения
  • Отправленный богатый push-уведомление с помощью Localitics Dashboard для обмена сообщениями - Устройство получает push-уведомление , но не проходит для NotificationService.cs c ode расширения службы уведомлений!

Это мой NotificationService код:

using System; 
using Foundation; 
using UserNotifications; 

namespace NotificationServiceExtension 
{ 
    [Register("NotificationService")] 
    public class NotificationService : UNNotificationServiceExtension 
    { 
     Action<UNNotificationContent> ContentHandler { get; set; } 
     UNMutableNotificationContent BestAttemptContent { get; set; } 
     const string ATTACHMENT_IMAGE_KEY = "ll_attachment_url"; 
     const string ATTACHMENT_TYPE_KEY = "ll_attachment_type"; 
     const string ATTACHMENT_FILE_NAME = "-localytics-rich-push-attachment."; 

     protected NotificationService(IntPtr handle) : base(handle) 
     { 
      // Note: this .ctor should not contain any initialization logic. 
     } 

     public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler) 
     { 
      System.Diagnostics.Debug.WriteLine("Notification Service DidReceiveNotificationRequest"); 
      ContentHandler = contentHandler; 
      BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy(); 
      if (BestAttemptContent != null) 
      { 
       string imageURL = null; 
       string imageType = null; 
       if (BestAttemptContent.UserInfo.ContainsKey(new NSString(ATTACHMENT_IMAGE_KEY))) 
       { 
        imageURL = BestAttemptContent.UserInfo.ValueForKey(new NSString(ATTACHMENT_IMAGE_KEY)).ToString(); 
       } 
       if (BestAttemptContent.UserInfo.ContainsKey(new NSString(ATTACHMENT_TYPE_KEY))) 
       { 
        imageType = BestAttemptContent.UserInfo.ValueForKey(new NSString(ATTACHMENT_TYPE_KEY)).ToString(); 
       } 

       if (imageURL == null || imageType == null) 
       { 
        ContentHandler(BestAttemptContent); 
        return; 
       } 
       var url = NSUrl.FromString(imageURL); 
       var task = NSUrlSession.SharedSession.CreateDownloadTask(url, (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 + ATTACHMENT_FILE_NAME + imageType; 
        var cacheFile = cachesFolder + fileName; 
        var attachmentURL = NSUrl.CreateFileUrl(cacheFile, false, null); 
        NSError err = null; 
        NSFileManager.DefaultManager.Move(tempFile, attachmentURL, out err); 
        if (err != null) 
        { 
         ContentHandler(BestAttemptContent); 
         return; 
        } 
        UNNotificationAttachmentOptions options = null; 
        var attachment = UNNotificationAttachment.FromIdentifier("localytics-rich-push-attachment", attachmentURL, options, out err); 
        if (attachment != null) 
        { 
         BestAttemptContent.Attachments = new UNNotificationAttachment[] { attachment }; 
        } 
        ContentHandler(BestAttemptContent); 
        return; 
       }); 
       task.Resume(); 
      } 
      else { 
       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); 
      return; 
     } 

    } 
} 
+0

Итак, в чем проблема? – Demitrian

+0

Устройство получает push-уведомление, но не передает код NotificationService.cs службы уведомлений! –

+0

Что значит «не проходит»? Вы имеете в виду, что 'DidReceiveNotificationRequest' не выполняется? – Demitrian

ответ

5

Вы делаете все правильно, это вопрос, поднятый некоторыми другими разработчиками Xamarin. Из того, что я могу сказать, как только вы запустите NSURLSession, чтобы что-то загрузить, даже если это супер супер мало, вы перейдете к пределу памяти, разрешенному для этого типа расширения. Это, скорее всего, очень специфично для ксамина. Вот ссылка на bugzilla. https://bugzilla.xamarin.com/show_bug.cgi?id=43985

Обход/взлом, который я нашел, далек от идеала. Я переписал это расширение приложения в xcode в объективе-c (вы можете использовать swift тоже, я полагаю). Это довольно небольшое (1 класс) расширение. Затем построил его в xcode, используя тот же профиль сертифицированной/подготовительной подписи кода, а затем нашел файл .appex в выводе xcode.

С этого момента вы можете взять «дешевый способ» и поменять этот файл .appex в своей .ipa-папке вручную перед отставкой и отправкой приложения. Если это будет достаточно для вас, вы можете остановиться здесь.

Или вы можете автоматизировать этот процесс, чтобы поместить файл-пример в расширение csproj и установить build-action как «content». Затем в этом файле csproj (вам нужно будет отредактировать напрямую) вы можете добавить что-то вроде этого. (В этом случае файл называется Notifications.Appex и помещается в папку под названием NativeExtension)

<Target Name="BeforeCodeSign"> 
    <ItemGroup> 
     <NativeExtensionDirectory Include="NativeExtension\Debug\**\*.*" /> 
    </ItemGroup> 

    <!-- cleanup the application extension built with Xamarin (too heavy in memory)--> 
    <RemoveDir SessionId="$(BuildSessionId)" 
       Directories="bin\iPhone\Debug\Notifications.appex"/> 

    <!-- copy the native one, built in obj-c --> 
    <Copy 
      SessionId="$(BuildSessionId)" 
      SourceFiles="@(NativeExtensionDirectory)" 
      DestinationFolder="bin\iPhone\Debug\Notifications.appex" 
      SkipUnchangedFiles="true" 
      OverwriteReadOnlyFiles="true" 
      Retries="3" 
      RetryDelayMilliseconds="300"/> 
</Target> 

Это дает общее представление, но, очевидно, если вы хотите поддержать Ad-Hoc распространения подписи, IOS распределение приложение-магазин подписи вам нужно будет добавить немного больше кода в это (и, возможно, добавить в csproj родной файл-приложение для каждой другой подписи), я бы предложил разместить такой XML-код в отдельный файл «.targets» и использовать условные calltargets в csproj. Нравится это:

<Target Name="BeforeCodeSign"> 
    <CallTarget Targets="ImportExtension_Debug" Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' " /> 
    <CallTarget Targets="ImportExtension" Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' " /> 
</Target> 
+0

Архив для публикации моего приложения -> Подписание и распространение с тем же сертификатом, что и для подписки на расширение Obj. Теперь я распаковал ipa и заменил апелкс. Сжатый и застегнутый молнией как ipa. Теперь я использовал этот инструмент для отказа от приложения (https://github.com/maciekish/iReSign). Может быть, есть проблема для отмены расширения, потому что у меня есть эта ошибка при установке приложения [_validateSignatureAndCopyInfoForURL: withOptions: error:]: 147: Не удалось проверить подпись кода .../extract/Payload/JRUITouch.app/PlugIns/NotificationServiceExtension.appex: 0xe8008001 ]. Знаете ли вы, какую команду выполнить для выхода из приложения? –

+0

Если вы используете iResign, он будет только подписывать весь ipa, но перед этим вам нужно подписать внутреннее приложение, а затем использовать ireign для подписания полного пакета ipa. Ниже приведен пример команды, которую вы можете выполнить перед распаковкой пакета ipa. codeign -f -s "имя центра сертификации" -i "com.company.app.notifications" --entitlements "../ExtensionEntitlements.plist" "Полезная нагрузка/MyApp.app/PlugIns/Notifications.appex" – oXeNoN

+0

I есть проблема, когда я пытаюсь установить на устройство после отставки 28 апреля 09:41:16 iPhone installd (MobileSystemServices) [3541] : 0x16dfef000 + [MICodeSigningVerifier _validateSignatureAndCopyInfoForURL: withOptions: error:]: 147: Не удалось проверить подпись кода/private/var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.QBb4HH/extract/Полезная нагрузка/JRUITouch.app/PlugIns/NotificationServiceExtension.appex: 0xe8008001 (Произошла неизвестная ошибка.) –

Смежные вопросы