Xamarin通知服务扩展问题 [英] Xamarin Notification Service Extension issue

查看:88
本文介绍了Xamarin通知服务扩展问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Notification Service Extension存在问题。
我已按照分步说明文件
https://developer.xamarin.com/guides/ios/platform_features/introduction-to-ios10/user-notifications/enhanced-user-notifications/#Working_with_Service_Extensions

I have an issue with Notification Service Extension. I have followed step by step documentation https://developer.xamarin.com/guides/ios/platform_features/introduction-to-ios10/user-notifications/enhanced-user-notifications/#Working_with_Service_Extensions

为了实现,我已经这样做了。

To implement, I have done in that way.


  • 添加了通知服务扩展我的应用程序的前缀相同(添加后缀,例如:APP:com.testapp.main - EXT:com.testapp.main.notificationextension)

  • 创建的APPID标识符com.testapp.main .notificationextension into Apple Center

  • 创建证书和配置文件以发送APP ID的推送通知com.testapp.main.notificationextension

  • 导入到Xcode和Xamarin证书和配置

  • 使用refer构建我的应用程序通知到通知扩展参考。

  • 创建要上传到TestFlight的存档

  • 使用其分发证书和配置文件签名的应用程序

  • 带有分发证书和配置文件的签名扩展

  • 上传到TestFlight

  • 下载并允许我的应用推送通知

  • 使用Localytics Dashboard发送丰富推送通知以发送消息
    - 设备接收推送通知但未通过NotificationService.cs通知服务扩展代码!

  • Added Notification Service Extension with same prefix of my app (adding a suffix, ex: APP: com.testapp.main - EXT: com.testapp.main.notificationextension)
  • Created APPID identifier com.testapp.main.notificationextension into Member Center of Apple
  • Created certificate and provisioning profile to send push notification for APP ID com.testapp.main.notificationextension
  • Imported into Xcode and Xamarin certificate and provisioning
  • Build my app with reference to Notification Extension reference.
  • Created archive to upload to TestFlight
  • Signed app with its Distribution Certificate and Provisioning Profile
  • Signed extension with its Distribution Certificate and Provisioning Profile
  • Uploaded to TestFlight
  • Download and allowed push notification for my app
  • Sent rich push notification with Localytics Dashboard for messaging - Device receive push notification but not pass for NotificationService.cs code of Notification Service Extension!

这是我的NotificationService代码:

This is my NotificationService code:

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;
        }

    }
}


推荐答案

你正在做的一切正确,这是一些其他xamarin开发人员提出的问题。据我所知,只要你运行NSURLSession下载一些内容,即使它超级超级小,你也要超过这种扩展所允许的内存限制。这很可能是非常特殊的xamarin。
这是bugzilla的链接。
https://bugzilla.xamarin.com/show_bug.cgi?id= 43985

You are doing everything correctly, this is an issue raised by a few other xamarin developers. From what I can tell, as soon as you run the NSURLSession to download something, even if it's super super small, you go above the memory limit allowed for this type of extension. This is most probably very specific to xamarin. Here is the link to the bugzilla. https://bugzilla.xamarin.com/show_bug.cgi?id=43985

我找到的解决方法/黑客远非理想。我在objective-c中重写了xcode中的这个app扩展(你也可以使用swift)。这是一个相当小(1级)的扩展。然后使用相同的代码签名证书/配置文件在xcode中构建它,然后在xcode的输出中找到.appex文件。

The work-around/hack I found is far from ideal. I rewrote this app extension in xcode in objective-c (you could use swift too I suppose). It is a fairly small (1 class) extension. Then built it in xcode using the same code signature certificate / provisioning profile and then found the .appex file in the xcode's output.

从那时起,你可以采取便宜方式,并在辞职和提交应用程序之前手动将.appex文件交换到.ipa文件夹中。如果这对你来说足够好,你可以在这里停止。

From then, you can take the "cheap way", and swap this .appex file in your .ipa folder manually just before resigning and submitting the app. If that's good enough for you, you can stop here.

或者你可以自动化这个过程,为此,将appex文件放在csproj的扩展中并设置构建 - 作为内容的行动。然后在这个csproj的文件中(你需要直接编辑)你可以添加这样的东西。 (在这种情况下,该文件名为Notifications.appex,位于名为NativeExtension的文件夹中)

Or you can automate this process, to to so, place the appex file in the csproj's extension and set the build-action as "content". Then in this csproj's file (you'll need to edit directly) you can add something like this. (In this case, the file is called Notifications.appex and is placed in a folder called 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中添加每个不同签名的本机appex文件),我建议将此类xml代码放在单独的.targets文件中并使用条件csproj中的calltargets。像这样:

This gives you the general idea, but obviously if you want to support ad-hoc distribution signature, iOS app-store distribution signature you will need to add a bit more code into this (and possibly add in the csproj a native appex file for each different signature), I would suggest putting such xml code in separate ".targets" file and use conditional calltargets in the csproj. Like this:

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

这篇关于Xamarin通知服务扩展问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆