首页 > 解决方案 > 当链接器设置为“全部链接”时,会发生 Xamarin 错误。无法使用依赖服务

问题描述

现在,由于 UIWebView 已弃用,我必须将链接器设置为“全部链接”才能提交到 App Store。这样做时,我必须添加[Preserve(AllMembers = true)]到我的 DataStore 以使它们以这种方式工作,但后来我遇到了这个问题。

以下行将返回 null:

var dp = DependencyService.Get<ITextMeter>();

在研究了解决方案之后,似乎最好的答案是将以下行添加到 AppDelegate 中:

DependencyService.Register<ITextMeter, TextMeterImplementation>();

一旦我这样做了,我就开始收到这个异常:

DependencyService: System.MissingMethodException: Default constructor not found for [Interface] https://forums.xamarin.com/discussion/71072/dependencyservice-system-missingmethodexception-default-constructor-not-found-for-interface

我只想找到一个可行的解决方案,让一切都可以使用设置为“链接全部”的链接器。提前致谢。

文本仪表:

using System;
using Xamarin.Forms.Internals;

namespace RedSwipe.Services
{
    public interface ITextMeter
    {
        double MeasureTextSize(string text, double width, double fontSize, string fontName = null);
    }
}

TextMeter 实现:

using System.Drawing;
using Foundation;
using RedSwipe.iOS.Services;
using RedSwipe.Services;
using UIKit;

[assembly: Xamarin.Forms.Dependency(typeof(TextMeterImplementation))]
namespace RedSwipe.iOS.Services
{
    public class TextMeterImplementation : ITextMeter
    {

        public double MeasureTextSize(string text, double width, double fontSize, string fontName = null)
        {
            var nsText = new NSString(text);
            var boundSize = new SizeF((float)width, float.MaxValue);
            var options = NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesLineFragmentOrigin;

            if (fontName == null)
            {
                fontName = "HelveticaNeue";
            }

            var attributes = new UIStringAttributes
            {
                Font = UIFont.FromName(fontName, (float)fontSize)
            };

            var sizeF = nsText.GetBoundingRect(boundSize, options, attributes, null).Size;

            //return new Xamarin.Forms.Size((double)sizeF.Width, (double)sizeF.Height);
            return (double)sizeF.Height;
        }

    }
}

标签: xamarinxamarin.iosdependency-managementxamarin-linker

解决方案


将此添加[Preserve (AllMembers = true)]到您的TextMeterImplementation课前实施中。

你的代码会是这样的:

using System.Drawing;
using Foundation;
using RedSwipe.iOS.Services;
using RedSwipe.Services;
using UIKit;
using Xamarin.Forms.Internals; // Add This import

[assembly: Xamarin.Forms.Dependency(typeof(TextMeterImplementation))]
namespace RedSwipe.iOS.Services
{
    [Preserve (AllMembers = true)]
    public class TextMeterImplementation : ITextMeter
    {

        public double MeasureTextSize(string text, double width, double fontSize, string fontName = null)
        {
            var nsText = new NSString(text);
            var boundSize = new SizeF((float)width, float.MaxValue);
            var options = NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesLineFragmentOrigin;

            if (fontName == null)
            {
                fontName = "HelveticaNeue";
            }

            var attributes = new UIStringAttributes
            {
                Font = UIFont.FromName(fontName, (float)fontSize)
            };

            var sizeF = nsText.GetBoundingRect(boundSize, options, attributes, null).Size;

            //return new Xamarin.Forms.Size((double)sizeF.Width, (double)sizeF.Height);
            return (double)sizeF.Height;
        }

    }
}

推荐阅读