我们正在编写一个Visual Studio(Xamarin)跨平台应用程序,它将与我们编写的下一个应用程序共享相当多的功能,因此我们希望将该共享功能放入“库”中,以便我们对其进行测试,轻松分享等等。
我们发现编写跨平台库的唯一方法是使用标准的Xamarin DependencyService范例创建它,将其转换为NuGet包,然后将该包加载到我们的主应用程序中。无论好坏,我们在微软提供生成这样的NuGet库的模板之前做到了这一点,所以我们不得不自己动手。
这适用于Android,但现在我想获得适用于iOS的相同代码,它根本无法正常工作。没有错误,没有警告,但是当我运行应用程序并致电
时Client = DependencyService.Get<IClient>();
它只返回null。如果我查看输出/调试窗口,它将加载'Company.Client.Abstractions.dll'(包含IClient定义的根DLL),而不是iOS特定的'Company.Client.dll'(包含特定于iOS的IClient实现。)
这是我的nuspec文件:
<?xml version="1.0"?>
<package >
<metadata>
<id>Client</id>
<version>0.0.35</version>
<authors>Me</authors>
<owners>Company</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Stuff</description>
<releaseNotes>Initial release</releaseNotes>
<copyright>Copyright 2017 Company</copyright>
<dependencies>
<group targetFramework="MonoAndroid">
<dependency id="Xamarin.Forms" version="2.3.4.247" />
</group>
<group targetFramework="Xamarin.iOS10">
<dependency id="Xamarin.Forms" version="2.3.4.247" />
</group>
<group targetFramework="uap">
<dependency id="Xamarin.Forms" version="2.3.4.247" />
</group>
</dependencies>
</metadata>
<files>
<!-- Cross-platform reference assemblies -->
<file src="Company.Client.Abstractions\bin\Debug\Company.Client.Abstractions.dll" target="lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Company.Client.Abstractions.dll" />
<file src="Company.Client.Abstractions\bin\Debug\Company.Client.Abstractions.pdb" target="lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Company.Client.Abstractions.pdb" />
<!-- iOS reference assemblies -->
<file src="Company.Client.iOS\bin\iPhone\Debug\Company.Client.dll" target="lib\Xamarin.iOS10\Company.Client.dll" />
<file src="Company.Client.iOS\bin\iPhone\Debug\Company.Client.pdb" target="lib\Xamarin.iOS10\Company.Client.pdb" />
<!-- Android reference assemblies -->
<file src="Company.Client.Android\bin\Debug\Company.Client.dll" target="lib\MonoAndroid10\Company.Client.dll" />
<file src="Company.Client.Android\bin\Debug\Company.Client.pdb" target="lib\MonoAndroid10\Company.Client.pdb" />
<!-- UWP reference assemblies -->
<file src="Company.Client.UWP\bin\Debug\Company.Client.dll" target="lib\UAP10\Company.Client.dll" />
<file src="Nuvectra.Client.UWP\bin\Debug\Company.Client.pdb" target="lib\UAP10\Company.Client.pdb" />
</files>
</package>
我认为有两类可能的问题:
查看生成的DLL,Android DLL长28k,iOS DLL为23k,因此看起来iOS DLL不是空的。有没有一个工具可以让我检查iOS DLL并确保它有必要的入口点?
生成iOS DLL的项目具有以下设置:
Target framework: Xamarin.iOS
Output type: Class Library
Condition compilation symbols: __ UNIFIED__;__ MOBILE__;__ IOS__
Platform: Active (Any CPU)
使用DLL的应用程序具有iOS项目的这些设置:
SDK Version: Default
Linker Behavior: Don't Link
Platform: Active (iPhone)
Supported Architectures: ARMv7 + ARM64
Target framework: Xamarin.IOS
Output type: Console Application
Conditional compilation symbols: __ UNIFIED__;__ MOBILE__;__ IOS__
我的'Abstractions'项目中的界面定义如下所示:
namespace Company.Client
{
public abstract class IClient
{
void abstract function();
}
}
我的iOS项目中的实现如下所示:
using Company.Client.iOS;
[assembly: Xamarin.Forms.Dependency (typeof (IosClient))]
namespace Company.Client.iOS
{
public class IosClient : IClient
{
void override function();
}
}
答案 0 :(得分:0)
我们尝试了许多不同的方法来创建一个NuGet包,其中包含使用DependencyService加载的特定于平台的代码,并且每种方式都有相同的问题 - 在Android下工作正常,在iOS下失败。
解决方案是在iOS库中创建一个使用DependencyService not 加载的类,然后在iOS应用程序中创建该类的实例。这足以说服iOS应用程序它实际上需要加载iOS库DLL,然后其余的DependencyService魔法正常工作。